17d8ebbb7SMasatake YAMATO /*
27d8ebbb7SMasatake YAMATO *
37d8ebbb7SMasatake YAMATO * Copyright (c) 2016, Masatake YAMATO
47d8ebbb7SMasatake YAMATO * Copyright (c) 2016, Red Hat, K.K.
57d8ebbb7SMasatake YAMATO *
67d8ebbb7SMasatake YAMATO * This source code is released for free distribution under the terms of the
77d8ebbb7SMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
87d8ebbb7SMasatake YAMATO *
97d8ebbb7SMasatake YAMATO * This module contains functions for generating tags for maven2 project model
107d8ebbb7SMasatake YAMATO * defined in http://maven.apache.org/POM/4.0.0,
117d8ebbb7SMasatake YAMATO * http://maven.apache.org/maven-v4_0_0.xsd.
127d8ebbb7SMasatake YAMATO */
137d8ebbb7SMasatake YAMATO
147d8ebbb7SMasatake YAMATO #include "general.h" /* must always come first */
157d8ebbb7SMasatake YAMATO
1614781660SMasatake YAMATO #include "entry.h"
177d8ebbb7SMasatake YAMATO #include "parse.h"
187d8ebbb7SMasatake YAMATO #include "read.h"
197d8ebbb7SMasatake YAMATO #include "routines.h"
207d8ebbb7SMasatake YAMATO #include "selectors.h"
210567d522SMasatake YAMATO #include "xml.h"
227d8ebbb7SMasatake YAMATO
239141951dSMasatake YAMATO #include <string.h>
249141951dSMasatake YAMATO
257d8ebbb7SMasatake YAMATO typedef enum {
2670d532f5SMasatake YAMATO K_GROUP_ID, K_ARTIFACT_ID, K_PROPERTY, K_REPOSITORY_ID
277d8ebbb7SMasatake YAMATO } maven2Kind;
287d8ebbb7SMasatake YAMATO
297d8ebbb7SMasatake YAMATO typedef enum {
307d8ebbb7SMasatake YAMATO R_GROUP_ID_PARENT,
315e9ed16aSMasatake YAMATO R_GROUP_ID_DEPENDENCY,
327d8ebbb7SMasatake YAMATO } maven2GroupIdRole;
337d8ebbb7SMasatake YAMATO
347d8ebbb7SMasatake YAMATO typedef enum {
357d8ebbb7SMasatake YAMATO R_ARTIFACT_ID_PARENT,
365e9ed16aSMasatake YAMATO R_ARTIFACT_ID_DEPENDENCY,
377d8ebbb7SMasatake YAMATO } maven2ArtifactIdRole;
387d8ebbb7SMasatake YAMATO
3913457258SMasatake YAMATO static roleDefinition Maven2GroupIdRoles [] = {
40ce990805SThomas Braun { true, "parent", "parent" },
41ce990805SThomas Braun { true, "dependency", "dependency" },
427d8ebbb7SMasatake YAMATO };
437d8ebbb7SMasatake YAMATO
4413457258SMasatake YAMATO static roleDefinition Maven2ArtifactIdRoles [] = {
45ce990805SThomas Braun { true, "parent", "parent" },
46ce990805SThomas Braun { true, "dependency", "dependency" },
477d8ebbb7SMasatake YAMATO };
487d8ebbb7SMasatake YAMATO
49e112e8abSMasatake YAMATO static kindDefinition Maven2Kinds [] = {
50ce990805SThomas Braun { true, 'g', "groupId", "group identifiers",
51ce990805SThomas Braun .referenceOnly = false, ATTACH_ROLES (Maven2GroupIdRoles) },
52ce990805SThomas Braun { true, 'a', "artifactId", "artifact identifiers",
53ce990805SThomas Braun .referenceOnly = false, ATTACH_ROLES (Maven2ArtifactIdRoles) },
54ce990805SThomas Braun { true, 'p', "property", "properties" },
55ce990805SThomas Braun { true, 'r', "repositoryId", "repository identifiers" },
567d8ebbb7SMasatake YAMATO };
577d8ebbb7SMasatake YAMATO
587d8ebbb7SMasatake YAMATO static void makeTagWithScope (xmlNode *node,
59513a7223SMasatake YAMATO const char *xpath,
607d8ebbb7SMasatake YAMATO const struct sTagXpathMakeTagSpec *spec,
617d8ebbb7SMasatake YAMATO struct sTagEntryInfo *tag,
627d8ebbb7SMasatake YAMATO void *userData);
637d8ebbb7SMasatake YAMATO
648df526f3SMasatake YAMATO static void makeTagRecursively (xmlNode *node,
65513a7223SMasatake YAMATO const char *xpath,
668df526f3SMasatake YAMATO const struct sTagXpathRecurSpec *spec,
678df526f3SMasatake YAMATO xmlXPathContext *ctx,
688df526f3SMasatake YAMATO void *userData);
69c8c96a79SMasatake YAMATO
makeTagForProperties(xmlNode * node,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathRecurSpec * spec CTAGS_ATTR_UNUSED,xmlXPathContext * ctx CTAGS_ATTR_UNUSED,void * userData CTAGS_ATTR_UNUSED)707d8ebbb7SMasatake YAMATO static void makeTagForProperties (xmlNode *node,
71513a7223SMasatake YAMATO const char *xpath CTAGS_ATTR_UNUSED,
728ccb7ee9SJiří Techet const struct sTagXpathRecurSpec *spec CTAGS_ATTR_UNUSED,
738ccb7ee9SJiří Techet xmlXPathContext *ctx CTAGS_ATTR_UNUSED,
748ccb7ee9SJiří Techet void *userData CTAGS_ATTR_UNUSED)
757d8ebbb7SMasatake YAMATO {
767d8ebbb7SMasatake YAMATO const xmlChar* str;
777d8ebbb7SMasatake YAMATO tagEntryInfo tag;
787d8ebbb7SMasatake YAMATO
797d8ebbb7SMasatake YAMATO str = node->name;
8016a2541cSMasatake YAMATO initTagEntry (&tag, (char *)str, K_PROPERTY);
817d8ebbb7SMasatake YAMATO tag.lineNumber = xmlGetLineNo (node);
827d8ebbb7SMasatake YAMATO tag.filePosition = getInputFilePositionForLine (tag.lineNumber);
837d8ebbb7SMasatake YAMATO
847d8ebbb7SMasatake YAMATO makeTagEntry (&tag);
857d8ebbb7SMasatake YAMATO }
867d8ebbb7SMasatake YAMATO
878df526f3SMasatake YAMATO
888df526f3SMasatake YAMATO enum maven2XpathTable {
898df526f3SMasatake YAMATO TABLE_MAIN,
908df526f3SMasatake YAMATO TABLE_PARENT,
918df526f3SMasatake YAMATO TABLE_DEPEDENCY,
928df526f3SMasatake YAMATO };
938df526f3SMasatake YAMATO
947d8ebbb7SMasatake YAMATO static tagXpathTable maven2XpathMainTable[] = {
957d8ebbb7SMasatake YAMATO { "/*[local-name()='project']/*[local-name()='groupId']",
967d8ebbb7SMasatake YAMATO LXPATH_TABLE_DO_MAKE,
9724b256e3SMasatake YAMATO { .makeTagSpec = { K_GROUP_ID, ROLE_DEFINITION_INDEX,
98a9bb575fSMasatake YAMATO makeTagWithScope } }
997d8ebbb7SMasatake YAMATO },
10082d40db9SMasatake YAMATO { "/*[local-name()='project']/*[local-name()='parent']",
10182d40db9SMasatake YAMATO LXPATH_TABLE_DO_RECUR,
1028df526f3SMasatake YAMATO { .recurSpec = { makeTagRecursively, TABLE_PARENT } }
1037d8ebbb7SMasatake YAMATO },
104c8c96a79SMasatake YAMATO { "/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency']",
105c8c96a79SMasatake YAMATO LXPATH_TABLE_DO_RECUR,
1068df526f3SMasatake YAMATO { .recurSpec = { makeTagRecursively, TABLE_DEPEDENCY } }
1075e9ed16aSMasatake YAMATO },
1087d8ebbb7SMasatake YAMATO { "/*[local-name()='project']/*[local-name()='artifactId']",
1097d8ebbb7SMasatake YAMATO LXPATH_TABLE_DO_MAKE,
11024b256e3SMasatake YAMATO { .makeTagSpec = { K_ARTIFACT_ID, ROLE_DEFINITION_INDEX,
111a9bb575fSMasatake YAMATO makeTagWithScope } }
1127d8ebbb7SMasatake YAMATO },
1137d8ebbb7SMasatake YAMATO { "/*[local-name()='project']/*[local-name()='properties']/*",
1147d8ebbb7SMasatake YAMATO LXPATH_TABLE_DO_RECUR,
115a9bb575fSMasatake YAMATO { .recurSpec = { makeTagForProperties } }
1167d8ebbb7SMasatake YAMATO },
11770d532f5SMasatake YAMATO { "/*[local-name()='project']/*[local-name()='repositories']/*[local-name()='repository']/*[local-name()='id']",
11870d532f5SMasatake YAMATO LXPATH_TABLE_DO_MAKE,
11924b256e3SMasatake YAMATO { .makeTagSpec = { K_REPOSITORY_ID, ROLE_DEFINITION_INDEX, } }
12070d532f5SMasatake YAMATO },
1217d8ebbb7SMasatake YAMATO };
1227d8ebbb7SMasatake YAMATO
12382d40db9SMasatake YAMATO static tagXpathTable maven2XpathParentTable[] = {
12482d40db9SMasatake YAMATO { "./*[local-name()='groupId']",
12582d40db9SMasatake YAMATO LXPATH_TABLE_DO_MAKE,
12682d40db9SMasatake YAMATO { .makeTagSpec = { K_GROUP_ID, R_GROUP_ID_PARENT,
12782d40db9SMasatake YAMATO makeTagWithScope } }
12882d40db9SMasatake YAMATO },
12982d40db9SMasatake YAMATO { "./*[local-name()='artifactId']",
13082d40db9SMasatake YAMATO LXPATH_TABLE_DO_MAKE,
13182d40db9SMasatake YAMATO { .makeTagSpec = { K_ARTIFACT_ID, R_ARTIFACT_ID_PARENT,
13282d40db9SMasatake YAMATO makeTagWithScope } }
13382d40db9SMasatake YAMATO },
13482d40db9SMasatake YAMATO };
13582d40db9SMasatake YAMATO
136c8c96a79SMasatake YAMATO static tagXpathTable maven2XpathDependencyTable[] = {
137c8c96a79SMasatake YAMATO { "./*[local-name()='groupId']",
138c8c96a79SMasatake YAMATO LXPATH_TABLE_DO_MAKE,
139c8c96a79SMasatake YAMATO { .makeTagSpec = { K_GROUP_ID, R_GROUP_ID_DEPENDENCY,
140c8c96a79SMasatake YAMATO makeTagWithScope } }
141c8c96a79SMasatake YAMATO },
142c8c96a79SMasatake YAMATO { "./*[local-name()='artifactId']",
143c8c96a79SMasatake YAMATO LXPATH_TABLE_DO_MAKE,
144c8c96a79SMasatake YAMATO { .makeTagSpec = { K_ARTIFACT_ID, R_ARTIFACT_ID_DEPENDENCY,
145c8c96a79SMasatake YAMATO makeTagWithScope } }
146c8c96a79SMasatake YAMATO },
147c8c96a79SMasatake YAMATO };
148c8c96a79SMasatake YAMATO
1497d8ebbb7SMasatake YAMATO static tagXpathTableTable maven2XpathTableTable[] = {
1507d8ebbb7SMasatake YAMATO [TABLE_MAIN] = { ARRAY_AND_SIZE(maven2XpathMainTable) },
15182d40db9SMasatake YAMATO [TABLE_PARENT] = { ARRAY_AND_SIZE(maven2XpathParentTable) },
152c8c96a79SMasatake YAMATO [TABLE_DEPEDENCY] = { ARRAY_AND_SIZE(maven2XpathDependencyTable) },
1537d8ebbb7SMasatake YAMATO };
1547d8ebbb7SMasatake YAMATO
1559141951dSMasatake YAMATO typedef enum {
1569141951dSMasatake YAMATO F_VERSION,
1579141951dSMasatake YAMATO } maven2Field;
1589141951dSMasatake YAMATO
159b56bd065SMasatake YAMATO static fieldDefinition Maven2Fields [] = {
1609141951dSMasatake YAMATO {
1619141951dSMasatake YAMATO .name = "version",
1629141951dSMasatake YAMATO .description = "version of artifact",
163ce990805SThomas Braun .enabled = false,
1649141951dSMasatake YAMATO }
1659141951dSMasatake YAMATO };
1669141951dSMasatake YAMATO
attachVersionIfExisting(struct sTagEntryInfo * tag,xmlNode * node)1672f8b8175SMasatake YAMATO static char* attachVersionIfExisting (struct sTagEntryInfo *tag, xmlNode *node)
1689141951dSMasatake YAMATO {
1692f8b8175SMasatake YAMATO char *version = NULL;
1709141951dSMasatake YAMATO
1719141951dSMasatake YAMATO for (node = node->next; node != NULL; node = node->next)
1729141951dSMasatake YAMATO {
1739141951dSMasatake YAMATO if (strcmp ((char *)node->name, "version") == 0)
1749141951dSMasatake YAMATO {
1752f8b8175SMasatake YAMATO version = (char *)xmlNodeGetContent (node);
1769141951dSMasatake YAMATO break;
1779141951dSMasatake YAMATO }
1789141951dSMasatake YAMATO }
1799141951dSMasatake YAMATO if (version)
180aa4def17SMasatake YAMATO attachParserField (tag, false, Maven2Fields [F_VERSION].ftype, version);
1812f8b8175SMasatake YAMATO return version;
1829141951dSMasatake YAMATO }
1839141951dSMasatake YAMATO
makeTagWithScope(xmlNode * node,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathMakeTagSpec * spec,struct sTagEntryInfo * tag,void * userData)1849141951dSMasatake YAMATO static void makeTagWithScope (xmlNode *node,
185513a7223SMasatake YAMATO const char *xpath CTAGS_ATTR_UNUSED,
1867d8ebbb7SMasatake YAMATO const struct sTagXpathMakeTagSpec *spec,
1877d8ebbb7SMasatake YAMATO struct sTagEntryInfo *tag,
1887d8ebbb7SMasatake YAMATO void *userData)
1897d8ebbb7SMasatake YAMATO {
1907d8ebbb7SMasatake YAMATO int *corkIndexes = userData;
1917d8ebbb7SMasatake YAMATO int i;
1922f8b8175SMasatake YAMATO char* version = NULL;
1939141951dSMasatake YAMATO
194f92e6bf2SMasatake YAMATO if (tag->kindIndex == K_ARTIFACT_ID)
1952f8b8175SMasatake YAMATO version = attachVersionIfExisting (tag, node);
1969141951dSMasatake YAMATO
1977d8ebbb7SMasatake YAMATO i = makeTagEntry (tag);
1987d8ebbb7SMasatake YAMATO
1992f8b8175SMasatake YAMATO if (version)
2002f8b8175SMasatake YAMATO xmlFree (version);
2012f8b8175SMasatake YAMATO
202f92e6bf2SMasatake YAMATO if ((tag->kindIndex == K_GROUP_ID)
203f92e6bf2SMasatake YAMATO || (tag->kindIndex == K_ARTIFACT_ID))
2047d8ebbb7SMasatake YAMATO corkIndexes [spec->kind] = i;
2057d8ebbb7SMasatake YAMATO }
2067d8ebbb7SMasatake YAMATO
2077d8ebbb7SMasatake YAMATO static void
findMaven2TagsForTable(enum maven2XpathTable tindex,xmlNode * node,xmlXPathContext * ctx)208c8c96a79SMasatake YAMATO findMaven2TagsForTable (enum maven2XpathTable tindex,
209c8c96a79SMasatake YAMATO xmlNode *node,
210c8c96a79SMasatake YAMATO xmlXPathContext *ctx)
2117d8ebbb7SMasatake YAMATO {
2127d8ebbb7SMasatake YAMATO int corkIndexes [] = {
213f6027918SMasatake YAMATO [K_GROUP_ID] = CORK_NIL,
214f6027918SMasatake YAMATO [K_ARTIFACT_ID] = CORK_NIL,
2157d8ebbb7SMasatake YAMATO };
2167d8ebbb7SMasatake YAMATO
217971e7196SMasatake YAMATO findXMLTags (ctx, node, tindex, &corkIndexes);
2187d8ebbb7SMasatake YAMATO
2197d8ebbb7SMasatake YAMATO tagEntryInfo *tag = getEntryInCorkQueue (corkIndexes [K_ARTIFACT_ID]);
220*3671ad72SMasatake YAMATO if (tag && corkIndexes [K_GROUP_ID] != CORK_NIL)
2217d8ebbb7SMasatake YAMATO tag->extensionFields.scopeIndex = corkIndexes [K_GROUP_ID];
2227d8ebbb7SMasatake YAMATO }
2237d8ebbb7SMasatake YAMATO
makeTagRecursively(xmlNode * node,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathRecurSpec * spec,xmlXPathContext * ctx,void * userData CTAGS_ATTR_UNUSED)2248df526f3SMasatake YAMATO static void makeTagRecursively (xmlNode *node,
225513a7223SMasatake YAMATO const char *xpath CTAGS_ATTR_UNUSED,
2268df526f3SMasatake YAMATO const struct sTagXpathRecurSpec *spec,
2278df526f3SMasatake YAMATO xmlXPathContext *ctx,
2288ccb7ee9SJiří Techet void *userData CTAGS_ATTR_UNUSED)
22982d40db9SMasatake YAMATO {
2308df526f3SMasatake YAMATO findMaven2TagsForTable (spec->nextTable, node, ctx);
231c8c96a79SMasatake YAMATO }
232c8c96a79SMasatake YAMATO
233c8c96a79SMasatake YAMATO static void
findMaven2Tags(void)234c8c96a79SMasatake YAMATO findMaven2Tags (void)
235c8c96a79SMasatake YAMATO {
2360567d522SMasatake YAMATO scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
237c8c96a79SMasatake YAMATO }
238c8c96a79SMasatake YAMATO
2390567d522SMasatake YAMATO static void
runXPathEngine(xmlSubparser * s,xmlXPathContext * ctx,xmlNode * root)2400567d522SMasatake YAMATO runXPathEngine(xmlSubparser *s,
2410567d522SMasatake YAMATO xmlXPathContext *ctx, xmlNode *root)
2420567d522SMasatake YAMATO {
2430567d522SMasatake YAMATO findMaven2TagsForTable (TABLE_MAIN, root, ctx);
2440567d522SMasatake YAMATO }
2450567d522SMasatake YAMATO
2460567d522SMasatake YAMATO static xmlSubparser maven2Subparser = {
2470567d522SMasatake YAMATO .subparser = {
2480567d522SMasatake YAMATO .direction = SUBPARSER_BI_DIRECTION,
2490567d522SMasatake YAMATO },
2500567d522SMasatake YAMATO .runXPathEngine = runXPathEngine,
2510567d522SMasatake YAMATO };
2520567d522SMasatake YAMATO
2537d8ebbb7SMasatake YAMATO extern parserDefinition*
Maven2Parser(void)2547d8ebbb7SMasatake YAMATO Maven2Parser (void)
2557d8ebbb7SMasatake YAMATO {
2567fcb59fbSMasatake YAMATO static const char *const extensions [] = { "pom", "xml", NULL };
2577d8ebbb7SMasatake YAMATO static const char *const patterns [] = { "pom.xml", NULL };
2587d8ebbb7SMasatake YAMATO parserDefinition* const def = parserNew ("Maven2");
259ff522ef8SMasatake YAMATO static selectLanguage selectors[] = { selectByXpathFileSpec, NULL };
2607d8ebbb7SMasatake YAMATO
2617fcb59fbSMasatake YAMATO static xpathFileSpec xpathFileSpecs[] = {
2627fcb59fbSMasatake YAMATO {
2637fcb59fbSMasatake YAMATO .rootElementName = "project",
2647fcb59fbSMasatake YAMATO .rootNSHref = "http://maven.apache.org/POM/4.0.0",
2657fcb59fbSMasatake YAMATO },
2667fcb59fbSMasatake YAMATO };
2677fcb59fbSMasatake YAMATO
2680567d522SMasatake YAMATO static parserDependency dependencies [] = {
2690567d522SMasatake YAMATO [0] = { DEPTYPE_SUBPARSER, "XML", &maven2Subparser },
2700567d522SMasatake YAMATO };
2710567d522SMasatake YAMATO
2720567d522SMasatake YAMATO def->dependencies = dependencies;
2730567d522SMasatake YAMATO def->dependencyCount = ARRAY_SIZE (dependencies);
2740567d522SMasatake YAMATO
27509ae690fSMasatake YAMATO def->kindTable = Maven2Kinds;
2767d8ebbb7SMasatake YAMATO def->kindCount = ARRAY_SIZE (Maven2Kinds);
2777d8ebbb7SMasatake YAMATO def->extensions = extensions;
2787d8ebbb7SMasatake YAMATO def->patterns = patterns;
2797d8ebbb7SMasatake YAMATO def->parser = findMaven2Tags;
2807d8ebbb7SMasatake YAMATO def->tagXpathTableTable = maven2XpathTableTable;
2817d8ebbb7SMasatake YAMATO def->tagXpathTableCount = ARRAY_SIZE (maven2XpathTableTable);
2826b1a862eSMasatake YAMATO def->useCork = CORK_QUEUE;
2837d8ebbb7SMasatake YAMATO def->selectLanguage = selectors;
284a739fa5fSMasatake YAMATO def->fieldTable = Maven2Fields;
285a739fa5fSMasatake YAMATO def->fieldCount = ARRAY_SIZE (Maven2Fields);
2867fcb59fbSMasatake YAMATO def->xpathFileSpecs = xpathFileSpecs;
2877fcb59fbSMasatake YAMATO def->xpathFileSpecCount = ARRAY_SIZE (xpathFileSpecs);
2887d8ebbb7SMasatake YAMATO return def;
2897d8ebbb7SMasatake YAMATO }
290