summaryrefslogtreecommitdiff
path: root/plugins/devkit
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2013-04-01 14:41:51 -0700
committerJean-Baptiste Queru <jbq@google.com>2013-04-01 14:41:51 -0700
commit2bd2b7c2623d4266384e890271869efc044aabff (patch)
tree0b31f50e55975b6354ed458314e17b4441bb4e17 /plugins/devkit
parent1d526b16d476792ca7ce47616d55833115e8d6ab (diff)
downloadidea-2bd2b7c2623d4266384e890271869efc044aabff.tar.gz
Snapshot ee98b298267d0e09d2cd2f0731b6480a56dd48e7 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I4515f72af131fdea9fc6905a4dc0fe9532409a81
Diffstat (limited to 'plugins/devkit')
-rw-r--r--plugins/devkit/devkit.iml10
-rw-r--r--plugins/devkit/lib/dtdparser113.jarbin0 -> 40982 bytes
-rw-r--r--plugins/devkit/resources/META-INF/plugin.xml4
-rw-r--r--plugins/devkit/src/build/PluginModuleBuildScopeProvider.java6
-rw-r--r--plugins/devkit/src/dom/generator/DTDModelLoader.java339
-rw-r--r--plugins/devkit/src/dom/generator/DomGenDialog.java79
-rw-r--r--plugins/devkit/src/dom/generator/DomGenPanel.form137
-rw-r--r--plugins/devkit/src/dom/generator/DomGenPanel.java177
-rw-r--r--plugins/devkit/src/dom/generator/Emitter.java36
-rw-r--r--plugins/devkit/src/dom/generator/FieldDesc.java78
-rw-r--r--plugins/devkit/src/dom/generator/FileManager.java33
-rw-r--r--plugins/devkit/src/dom/generator/GenerateDomModelAction.java34
-rw-r--r--plugins/devkit/src/dom/generator/JetBrainsEmitter.java679
-rw-r--r--plugins/devkit/src/dom/generator/Main.java61
-rw-r--r--plugins/devkit/src/dom/generator/MergingFileManager.java248
-rw-r--r--plugins/devkit/src/dom/generator/ModelDesc.java171
-rw-r--r--plugins/devkit/src/dom/generator/ModelGen.java189
-rw-r--r--plugins/devkit/src/dom/generator/ModelLoader.java28
-rw-r--r--plugins/devkit/src/dom/generator/NamespaceDesc.java84
-rw-r--r--plugins/devkit/src/dom/generator/TypeDesc.java55
-rw-r--r--plugins/devkit/src/dom/generator/Util.java224
-rw-r--r--plugins/devkit/src/dom/generator/XSDModelLoader.java681
-rw-r--r--plugins/devkit/src/dom/impl/InspectionsPropertiesReferenceProviderContributor.java4
-rw-r--r--plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java15
24 files changed, 3361 insertions, 11 deletions
diff --git a/plugins/devkit/devkit.iml b/plugins/devkit/devkit.iml
index a4dfa50b500e..cfc7dad256db 100644
--- a/plugins/devkit/devkit.iml
+++ b/plugins/devkit/devkit.iml
@@ -28,6 +28,16 @@
<orderEntry type="library" scope="TEST" name="Groovy" level="project" />
<orderEntry type="module" module-name="jps-builders" />
<orderEntry type="library" name="Guava" level="project" />
+ <orderEntry type="library" name="Xerces" level="project" />
+ <orderEntry type="module-library">
+ <library name="DTDParser">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/dtdparser113.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
</component>
</module>
diff --git a/plugins/devkit/lib/dtdparser113.jar b/plugins/devkit/lib/dtdparser113.jar
new file mode 100644
index 000000000000..4172640cb9d8
--- /dev/null
+++ b/plugins/devkit/lib/dtdparser113.jar
Binary files differ
diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml
index 099b9b23dfb4..667fcd76911f 100644
--- a/plugins/devkit/resources/META-INF/plugin.xml
+++ b/plugins/devkit/resources/META-INF/plugin.xml
@@ -140,6 +140,10 @@
<action internal="true" class="org.jetbrains.idea.devkit.actions.ShowSerializedXmlAction" text="Show Serialized XML for Class"
id="ShowSerializedXml"/>
+
+ <action internal="true" class="org.jetbrains.idea.devkit.dom.generator.GenerateDomModelAction" text="Generate Dom Model"
+ id="GenerateDomModel"/>
+
<add-to-group group-id="Internal" anchor="last"/>
</group>
diff --git a/plugins/devkit/src/build/PluginModuleBuildScopeProvider.java b/plugins/devkit/src/build/PluginModuleBuildScopeProvider.java
index d4899785a7f7..79bccac2c71e 100644
--- a/plugins/devkit/src/build/PluginModuleBuildScopeProvider.java
+++ b/plugins/devkit/src/build/PluginModuleBuildScopeProvider.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.devkit.module.PluginModuleType;
+import org.jetbrains.jps.api.CmdlineProtoUtil;
import org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTargetType;
@@ -35,7 +36,8 @@ import java.util.List;
public class PluginModuleBuildScopeProvider extends BuildTargetScopeProvider {
@NotNull
@Override
- public List<TargetTypeBuildScope> getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project) {
+ public List<TargetTypeBuildScope> getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter,
+ @NotNull Project project, boolean forceBuild) {
List<String> pluginArtifactTargetIds = new ArrayList<String>();
for (Module module : baseScope.getAffectedModules()) {
if (PluginModuleType.isOfType(module)) {
@@ -46,6 +48,6 @@ public class PluginModuleBuildScopeProvider extends BuildTargetScopeProvider {
if (pluginArtifactTargetIds.isEmpty()) {
return Collections.emptyList();
}
- return Collections.singletonList(TargetTypeBuildScope.newBuilder().setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId()).addAllTargetId(pluginArtifactTargetIds).build());
+ return Collections.singletonList(CmdlineProtoUtil.createTargetsScope(ArtifactBuildTargetType.INSTANCE.getTypeId(), pluginArtifactTargetIds, forceBuild));
}
}
diff --git a/plugins/devkit/src/dom/generator/DTDModelLoader.java b/plugins/devkit/src/dom/generator/DTDModelLoader.java
new file mode 100644
index 000000000000..4a49d6eacbcf
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/DTDModelLoader.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import com.wutka.dtd.*;
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * @author Gregory.Shrago
+ * @author Konstantin Bulenkov
+ */
+public class DTDModelLoader implements ModelLoader {
+ private ModelDesc model;
+
+ public void loadModel(ModelDesc model, Collection<File> schemas, XMLEntityResolver resolver) throws Exception {
+ this.model = model;
+ for (File dtdFile : schemas) {
+ String fileName = dtdFile.getPath();
+ if (dtdFile.isDirectory() || !fileName.endsWith(".dtd") || fileName.endsWith("datatypes.dtd")) {
+ Util.log("skipping " + fileName);
+ continue;
+ }
+ Util.log("loading " + fileName+"..");
+ String ns = fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1);
+ //loadDTDByXerces(ns, dtdFile, resolver);
+
+ loadDTDByWutka(ns, dtdFile);
+
+ }
+ }
+
+ private NamespaceDesc ensureNamespaceExists(String ns) {
+ if (!model.nsdMap.containsKey(ns)) {
+ Util.log("Adding default ns desc for: " + ns);
+ NamespaceDesc nsd = new NamespaceDesc(ns, model.nsdMap.get(""));
+ model.nsdMap.put(ns, nsd);
+ }
+ return model.nsdMap.get(ns);
+ }
+
+
+ private void loadDTDByWutka(String ns, File dtdFile) throws Exception {
+ DTDParser parser = new DTDParser(dtdFile, false);
+ // Parse the DTD and ask the parser to guess the root element
+ DTD dtd = parser.parse(true);
+ checkDTDRootElement(dtd);
+ processDTD(ns, dtd, model.jtMap, model.nsdMap);
+ }
+
+
+ private void processDTD(String namespace, DTD dtd, Map<String, TypeDesc> jtMap, Map<String, NamespaceDesc> nsdMap) {
+ final NamespaceDesc nsd = ensureNamespaceExists(namespace);
+ if (nsd.skip) return;
+ final ArrayList<String> resultQNames = new ArrayList<String>();
+ final DTDElement[] elements = new DTDElement[dtd.elements.size()];
+ int ptr = 1;
+
+ final HashSet<DTDElement> visitedElements = new HashSet<DTDElement>();
+ elements[0] = dtd.rootElement;
+
+ while (--ptr > -1) {
+ final DTDElement el = elements[ptr];
+ visitedElements.add(el);
+ final String typeName = model.toJavaTypeName(el.name, namespace);
+ final String typeQName = model.toJavaQualifiedTypeName(namespace, typeName, false);
+ if (resultQNames.contains(typeQName)) {
+ continue;
+ } else {
+ resultQNames.add(typeQName);
+ }
+ final TypeDesc td = new TypeDesc(el.name, namespace, typeName, TypeDesc.TypeEnum.CLASS);
+ boolean duplicates = false;
+ if ((el.content instanceof DTDAny) || (el.content instanceof DTDMixed)) {
+ FieldDesc fd = new FieldDesc(FieldDesc.SIMPLE, "value", "String", null, "null", false);
+ fd.realIndex = td.fdMap.size();
+ td.fdMap.put(fd.name, fd);
+ }
+ for (Object o : el.attributes.keySet()) {
+ String attrName = (String) o;
+ DTDAttribute attr = (DTDAttribute) el.attributes.get(attrName);
+ if (attr.decl == DTDDecl.FIXED || "ID".equals(attr.type)) {
+ continue;
+ }
+ boolean required = attr.decl == DTDDecl.REQUIRED;
+ FieldDesc fd1 = new FieldDesc(FieldDesc.ATTR, Util.toJavaFieldName(attrName), "String", null, "\"\"", required);
+ fd1.tagName = attrName;
+ fd1.documentation = "Attribute " + attrName + "";
+ fd1.realIndex = td.fdMap.size();
+ duplicates = Util.addToNameMap(td.fdMap, fd1, false) || duplicates;
+ }
+ final ArrayList<List<DTDItem>> choiceList = new ArrayList<List<DTDItem>>();
+ final LinkedList<Entry> plist = new LinkedList<Entry>();
+ if (el.content instanceof DTDContainer) {
+ //if ((el.content instanceof DTDChoice) || (el.content instanceof DTDSequence)) {
+ plist.add(new Entry(el.content, false, true));
+ }
+ while (!plist.isEmpty()) {
+ final Entry pentry = plist.removeFirst();
+
+ final DTDItem p = pentry.p;
+
+ if (p instanceof DTDName) {
+ final DTDName n = (DTDName) p;
+ final DTDElement nel = (DTDElement) dtd.elements.get(n.value);
+ final String pName = n.value;
+ final FieldDesc fd1 = new FieldDesc(FieldDesc.STR, Util.toJavaFieldName(pName), pName, null, "null", pentry.required && (n.cardinal == DTDCardinal.ONEMANY || n.cardinal == DTDCardinal.NONE));
+ fd1.tagName = pName;
+ if (nel != null) {
+ fd1.documentation = parseDTDItemDocumentation(dtd, nel, "Type " + nel.name + " documentation");
+ }
+ if (nel == null) {
+ fd1.type = model.toJavaTypeName(fd1.tagName, namespace);
+ } else if (nel.content instanceof DTDEmpty || nel.content instanceof DTDAny) {
+ boolean hasAttrFields = false;
+ boolean hasTextContents = nel.content instanceof DTDAny;
+ for (Object o : nel.attributes.values()) {
+ DTDAttribute attr = (DTDAttribute) o;
+ if (attr.decl != DTDDecl.FIXED && !"ID".equals(attr.type)) {
+ hasAttrFields = true;
+ break;
+ }
+ }
+ if (hasAttrFields || hasTextContents) {
+ fd1.clType = FieldDesc.OBJ;
+ fd1.type = model.toJavaTypeName(fd1.tagName, namespace);
+ fd1.contentQualifiedName = model.toJavaQualifiedTypeName(namespace, fd1.name, false);
+ fd1.def = "null";
+ // next type
+ if (!visitedElements.contains(nel)) {
+ elements[ptr++] = nel;
+ }
+ } else if (hasTextContents) {
+ fd1.clType = FieldDesc.STR;
+ fd1.type = "String";
+ fd1.def = "null";
+ } else {
+ fd1.clType = FieldDesc.BOOL;
+ fd1.type = "boolean";
+ fd1.def = "false";
+ }
+ } else if (nel.content instanceof DTDContainer) {
+ boolean hasAttrFields = false;
+ boolean hasTextField = false;
+ if ((nel.content instanceof DTDMixed) && ((DTDMixed) nel.content).getItemsVec().size() == 1) {
+ hasTextField = true;
+ for (Object o : nel.attributes.values()) {
+ final DTDAttribute attr = (DTDAttribute) o;
+ if (attr.decl != DTDDecl.FIXED && !"ID".equals(attr.type)) {
+ hasAttrFields = true;
+ break;
+ }
+ }
+ }
+ if (hasTextField && !hasAttrFields) {
+ fd1.clType = FieldDesc.STR;
+ fd1.type = "String";
+ fd1.def = "null";
+ } else {
+ fd1.clType = FieldDesc.OBJ;
+ fd1.type = model.toJavaTypeName(fd1.tagName, namespace);
+ fd1.contentQualifiedName = model.toJavaQualifiedTypeName(namespace, fd1.tagName, false);
+ // next type
+ if (!visitedElements.contains(nel)) {
+ elements[ptr++] = nel;
+ }
+ }
+ } else {
+ fd1.type = "ERROR:Name";
+ }
+ if ((pentry.many || n.cardinal.type >= 2) && fd1.clType != FieldDesc.BOOL) {
+ fd1.elementType = fd1.type;
+ fd1.elementName = fd1.name;
+ fd1.type = "List<" + fd1.elementType + ">";
+ fd1.name = Util.pluralize(fd1.name);
+ fd1.def = "new ArrayList(0)";
+ fd1.clType = -fd1.clType;
+ fd1.comment = "array of " + fd1.elementType;
+ }
+ fd1.realIndex = td.fdMap.size();
+ duplicates = Util.addToNameMap(td.fdMap, fd1, false) || duplicates;
+ } else if (p instanceof DTDContainer) {
+ final DTDContainer cont = (DTDContainer) p;
+ final boolean isChoice = cont instanceof DTDChoice;
+ // 0 - NONE, 1 - OPT, 2 - ZEROMANY, 3 - ONEMANY
+ final boolean required = !isChoice && pentry.required && p.cardinal != DTDCardinal.ZEROMANY && p.cardinal != DTDCardinal.OPTIONAL;
+ final boolean many = p.cardinal == DTDCardinal.ONEMANY || p.cardinal == DTDCardinal.ZEROMANY;
+ List<DTDItem> l = cont.getItemsVec();
+ if (!many && isChoice) {
+ choiceList.add(l);
+ }
+ for (DTDItem aL : l) {
+ plist.add(new Entry(aL, many, required));
+ }
+ } else {
+ Util.logerr("unknown item " + p);
+ }
+ }
+ td.duplicates = duplicates;
+ td.documentation = parseDTDItemDocumentation(dtd, el, "Type " + el.name + " documentation");
+ jtMap.put(model.toJavaQualifiedTypeName(namespace, td.name, false), td);
+ int i = 0;
+ for (FieldDesc fd : td.fdMap.values()) {
+ fd.idx = i++;
+ }
+ for (List<DTDItem> l : choiceList) {
+ ArrayList<DTDItem> clist = new ArrayList<DTDItem>();
+ LinkedList<DTDItem> elist = new LinkedList<DTDItem>();
+ for (i = 0; i < l.size(); i++) {
+ elist.add(l.get(i));
+ }
+ while (!elist.isEmpty()) {
+ DTDItem p = elist.removeFirst();
+ if (p instanceof DTDContainer) {
+ List<DTDItem> l2 = ((DTDContainer) p).getItemsVec();
+ for (DTDItem aL2 : l2) {
+ elist.addFirst(aL2);
+ }
+ } else if (p instanceof DTDName) {
+ clist.add(p);
+ }
+ }
+ boolean choiceOpt = true;
+ FieldDesc[] choice = new FieldDesc[clist.size()];
+ for (i = 0; i < choice.length; i++) {
+ DTDName p = (DTDName) clist.get(i);
+ String s = Util.toJavaFieldName(p.value);
+ FieldDesc fd = td.fdMap.get(s);
+ if (fd == null) {
+ fd = td.fdMap.get(Util.pluralize(s));
+ if (fd == null) {
+ Util.logerr("uknown choice element: " + s);
+ continue;
+ }
+ }
+ choice[i] = fd;
+ choice[i].choice = choice;
+ if (fd.required) choiceOpt = false;
+ }
+ for (i = 0; i < choice.length; i++) {
+ choice[i].choiceOpt = choiceOpt;
+ }
+ }
+ }
+ List<DTDEntity> entList = dtd.getItemsByType(DTDEntity.class);
+ for (DTDEntity entity : entList) {
+ String value = entity.value;
+ if (!value.startsWith("(") || !value.endsWith(")")) {
+ continue;
+ }
+ String typeName = model.toJavaTypeName(entity.name, namespace);
+ TypeDesc td = new TypeDesc(entity.name, namespace, typeName, TypeDesc.TypeEnum.ENUM);
+ StringTokenizer st = new StringTokenizer(value, "(|)");
+ while (st.hasMoreTokens()) {
+ final String s = st.nextToken();
+ td.fdMap.put(s, new FieldDesc(Util.computeEnumConstantName(s, td.name), s));
+ }
+ td.documentation = parseDTDItemDocumentation(dtd, entity, "Type " + entity.name + " documentation");
+ jtMap.put(model.toJavaQualifiedTypeName(namespace, td.name, true), td);
+ }
+ }
+
+ private static String parseDTDItemDocumentation(DTD dtd, DTDOutput obj, String title) {
+ int elementIndex = dtd.items.indexOf(obj);
+ if (elementIndex < 1) return null;
+ Object prev = dtd.items.get(elementIndex - 1);
+ if (!(prev instanceof DTDComment)) return null;
+ DTDComment comment = (DTDComment) prev;
+ return title + "\n" + "<pre>\n" + comment.getText() + "\n</pre>";
+ }
+
+ static class Entry {
+ boolean required;
+ boolean many;
+ DTDItem p;
+
+ Entry(DTDItem p, boolean many, boolean required) {
+ this.required = required;
+ this.many = many;
+ this.p = p;
+ }
+
+ Entry parent;
+ DTDItem it;
+ Vector choice;
+ int num;
+
+ Entry(Entry parent, DTDItem it, Vector choice, int num) {
+ this.parent = parent;
+ this.it = it;
+ this.choice = choice;
+ this.num = num;
+ }
+ }
+
+
+ private static void checkDTDRootElement(DTD dtd) throws Exception {
+ if (dtd.rootElement == null) {
+ StringBuffer sb = new StringBuffer("Empty root: possible elements: ");
+ HashMap map = new HashMap(dtd.elements);
+ for (Object o : dtd.elements.values()) {
+ DTDElement el = (DTDElement) o;
+ if (el.content instanceof DTDContainer) {
+ for (Object obj : ((DTDContainer) el.content).getItemsVec()) {
+ if (obj instanceof DTDName) {
+ map.remove(((DTDName) obj).value);
+ }
+ }
+ }
+ }
+ if (dtd.rootElement != null) return;
+ sb.append(map.size()).append(map.keySet());
+ throw new Exception(sb.toString());
+ }
+ }
+
+}
diff --git a/plugins/devkit/src/dom/generator/DomGenDialog.java b/plugins/devkit/src/dom/generator/DomGenDialog.java
new file mode 100644
index 000000000000..52d2675e0ea3
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/DomGenDialog.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+
+import javax.swing.*;
+import java.io.File;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DomGenDialog extends DialogWrapper{
+ final DomGenPanel panel;
+ final JComponent comp;
+
+ protected DomGenDialog(Project project) {
+ super(project);
+ panel = new DomGenPanel(project);
+ comp = panel.getComponent();
+ panel.restore();
+ setTitle("Generate Dom Model from XSD or DTD");
+ init();
+ getOKAction().putValue(Action.NAME, "Generate");
+ }
+
+ @Override
+ protected JComponent createCenterPanel() {
+ return comp;
+ }
+
+ @Override
+ protected void doOKAction() {
+ if (!panel.validate()) return;
+ final String location = panel.getLocation();
+ ModelLoader loader = location.toLowerCase().endsWith(".xsd") ? new XSDModelLoader() : new DTDModelLoader();
+ final JetBrainsEmitter emitter = new JetBrainsEmitter();
+ final MergingFileManager fileManager = new MergingFileManager();
+ if (panel.getAuthor().trim().length() > 0) {
+ emitter.setAuthor(panel.getAuthor());
+ }
+ final ModelGen modelGen = new ModelGen(loader, emitter, fileManager);
+ final NamespaceDesc desc = panel.getNamespaceDescriptor();
+ modelGen.setConfig(desc.name, location, desc, panel.getSkippedSchemas());
+ try {
+ final File output = new File(panel.getOutputDir());
+ modelGen.perform(output, new File(location).getParentFile());
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ }
+ panel.saveAll();
+ super.doOKAction();
+ }
+
+ @Override
+ public void doCancelAction() {
+ panel.saveAll();
+ super.doCancelAction();
+ }
+
+ @Override
+ protected String getDimensionServiceKey() {
+ return getClass().getName();
+ }
+}
diff --git a/plugins/devkit/src/dom/generator/DomGenPanel.form b/plugins/devkit/src/dom/generator/DomGenPanel.form
new file mode 100644
index 000000000000..1cc5978d395b
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/DomGenPanel.form
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.devkit.dom.generator.DomGenPanel">
+ <grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="8" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="20" y="20" width="424" height="262"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ </clientProperties>
+ <border type="none" title="Dom Generator Config"/>
+ <children>
+ <component id="29b47" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Namespace:"/>
+ </properties>
+ </component>
+ <vspacer id="e8ccd">
+ <constraints>
+ <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ <component id="f5680" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Super Class:"/>
+ </properties>
+ </component>
+ <component id="20f66" class="javax.swing.JTextField" binding="mySuperClass">
+ <constraints>
+ <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="327" height="22"/>
+ </grid>
+ </constraints>
+ <properties>
+ <text value="com.intellij.util.xml.DomElement"/>
+ </properties>
+ </component>
+ <component id="4a359" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Package:"/>
+ </properties>
+ </component>
+ <component id="afd05" class="javax.swing.JTextField" binding="myPackage">
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="327" height="22"/>
+ </grid>
+ </constraints>
+ <properties>
+ <text value="com.intellij.myFramework.model"/>
+ </properties>
+ </component>
+ <component id="d62dc" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Output Dir:"/>
+ </properties>
+ </component>
+ <component id="6a48b" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myOutputDir" custom-create="true">
+ <constraints>
+ <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="327" height="22"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="7fb9d" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="mySchemaLocation" custom-create="true">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="327" height="22"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="7940e" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Scheme File:"/>
+ </properties>
+ </component>
+ <component id="833b2" class="javax.swing.JTextField" binding="myNamespace">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="327" height="22"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="bdaaf" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Skip schemes:"/>
+ </properties>
+ </component>
+ <component id="f4732" class="javax.swing.JTextArea" binding="mySkipSchemas">
+ <constraints>
+ <grid row="6" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="50"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="54b59" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="@author:"/>
+ </properties>
+ </component>
+ <component id="b033e" class="javax.swing.JTextField" binding="myAuthor">
+ <constraints>
+ <grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+</form>
diff --git a/plugins/devkit/src/dom/generator/DomGenPanel.java b/plugins/devkit/src/dom/generator/DomGenPanel.java
new file mode 100644
index 000000000000..df2a6d8e8701
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/DomGenPanel.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.fileChooser.FileTypeDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.xml.XmlAttribute;
+import com.intellij.psi.xml.XmlDocument;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.util.ArrayUtil;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.ArrayList;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DomGenPanel {
+ private JPanel mainPanel;
+ private JTextField myNamespace;
+ private JTextField mySuperClass;
+ private TextFieldWithBrowseButton mySchemaLocation;
+ private JTextField myPackage;
+ private TextFieldWithBrowseButton myOutputDir;
+ private JTextArea mySkipSchemas;
+ private JTextField myAuthor;
+ private final Project myProject;
+
+ public DomGenPanel(Project project) {
+ myProject = project;
+ }
+
+ private void createUIComponents() {
+ mySchemaLocation = new TextFieldWithBrowseButton();
+ final String title = "Choose XSD or DTD schema";
+ mySchemaLocation.addBrowseFolderListener(title, "Make sure there are only necessary schemes in directory where your XSD or DTD schema is located", myProject, new FileTypeDescriptor(title, "xsd", "dtd"));
+ mySchemaLocation.getTextField().setEditable(false);
+ mySchemaLocation.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ final File file = new File(mySchemaLocation.getText());
+ if (file.exists() && file.getName().toLowerCase().endsWith(".xsd")) {
+ final VirtualFile vf = LocalFileSystem.getInstance().findFileByIoFile(file);
+ if (vf != null) {
+ final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vf);
+ if (psiFile instanceof XmlFile) {
+ final XmlDocument xml = ((XmlFile)psiFile).getDocument();
+ if (xml != null) {
+ final XmlTag rootTag = xml.getRootTag();
+ if (rootTag != null) {
+ String target = null;
+ ArrayList<String> ns = new ArrayList<String>();
+ for (XmlAttribute attr : rootTag.getAttributes()) {
+ if ("targetNamespace".equals(attr.getName())) {
+ target = attr.getValue();
+ }
+ else if (attr.getName().startsWith("xmlns")) {
+ ns.add(attr.getValue());
+ }
+ }
+
+ ns.remove(target);
+ if (target != null) {
+ myNamespace.setText(target);
+ }
+ mySkipSchemas.setText(StringUtil.join(ArrayUtil.toStringArray(ns), "\n"));
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+ myOutputDir = new TextFieldWithBrowseButton();
+ myOutputDir.addBrowseFolderListener("Select Output For Generated Files", "", myProject, FileChooserDescriptorFactory.getDirectoryChooserDescriptor("Output For Generated Files"));
+ }
+
+ public JComponent getComponent() {
+ return mainPanel;
+ }
+
+ public NamespaceDesc getNamespaceDescriptor() {
+ return new NamespaceDesc(myNamespace.getText().trim(), myPackage.getText().trim(), mySuperClass.getText().trim(), "", null, null, null, null);
+ }
+
+ public String getLocation() {
+ return mySchemaLocation.getText();
+ }
+
+ public String getOutputDir() {
+ return myOutputDir.getText();
+ }
+
+ private static final String PREFIX = "DomGenPanel.";
+ public void restore() {
+ myNamespace.setText(getValue("namespace", ""));
+ myPackage.setText(getValue("package", "com.intellij.myframework.model"));
+ mySchemaLocation.setText(getValue("schemaLocation", ""));
+ mySuperClass.setText(getValue("superClass", "com.intellij.util.xml.DomElement"));
+ myOutputDir.setText(getValue("output", ""));
+ mySkipSchemas.setText(getValue("skipSchemas", "http://www.w3.org/2001/XMLSchema\nhttp://www.w3.org/2001/XMLSchema-instance"));
+ myAuthor.setText(getValue("author", ""));
+ }
+
+ private static String getValue(String name, String defaultValue) {
+ return PropertiesComponent.getInstance().getOrInit(PREFIX + name, defaultValue);
+ }
+
+ private static void setValue(String name, String value) {
+ PropertiesComponent.getInstance().setValue(PREFIX + name, value);
+ }
+
+ public void saveAll() {
+ setValue("namespace", myNamespace.getText());
+ setValue("package", myPackage.getText());
+ setValue("schemaLocation", mySchemaLocation.getText());
+ setValue("superClass", mySuperClass.getText());
+ setValue("output", myOutputDir.getText());
+ setValue("skipSchemas", mySkipSchemas.getText());
+ setValue("author", myAuthor.getText());
+ }
+
+ public boolean validate() {
+ if (!new File(mySchemaLocation.getText()).exists()) {
+ Messages.showErrorDialog(myProject, "Schema location doesn't exist", "Error");
+ IdeFocusManager.getInstance(myProject).requestFocus(mySchemaLocation, true);
+ return false;
+ }
+
+ if (!new File(myOutputDir.getText()).exists()) {
+ Messages.showErrorDialog(myProject, "Output dir doesn't exist", "Error");
+ IdeFocusManager.getInstance(myProject).requestFocus(myOutputDir, true);
+ return false;
+ }
+
+ return true;
+ }
+
+ public String[] getSkippedSchemas() {
+ final String schemes = mySkipSchemas.getText().replaceAll("\r\n", "\n").trim();
+ if (schemes.length() > 0) {
+ return schemes.split("\n");
+ }
+ return new String[0];
+ }
+
+ public String getAuthor() {
+ return myAuthor.getText();
+ }
+}
diff --git a/plugins/devkit/src/dom/generator/Emitter.java b/plugins/devkit/src/dom/generator/Emitter.java
new file mode 100644
index 000000000000..4bc212f8a242
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/Emitter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public interface Emitter {
+ String JDOC_OPEN = "/**";
+ String JDOC_CONT = " * ";
+ String JDOC_CLOSE = " */";
+
+ void emit(FileManager fileManager, ModelDesc model, File outputRoot);
+}
diff --git a/plugins/devkit/src/dom/generator/FieldDesc.java b/plugins/devkit/src/dom/generator/FieldDesc.java
new file mode 100644
index 000000000000..13f3bf6e065f
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/FieldDesc.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class FieldDesc implements Comparable<FieldDesc> {
+ final static int STR = 1;
+ final static int BOOL = 2;
+ final static int OBJ = 3;
+ final static int ATTR = 4;
+ final static int DOUBLE = 5;
+ final static int SIMPLE = 6;
+
+ public FieldDesc(String name, String def) {
+ this.name = name;
+ this.def = def;
+ }
+
+ public FieldDesc(int clType, String name, String type, String elementType, String def, boolean required) {
+ this.clType = clType;
+ this.name = name;
+ this.type = type;
+ this.elementType = elementType;
+ this.def = def;
+ this.required = required;
+ }
+
+ int clType = STR;
+ String name;
+ String type;
+ String elementType;
+ String def;
+ boolean required;
+
+ int idx;
+ String tagName;
+ String elementName;
+ String comment;
+ FieldDesc[] choice;
+ boolean choiceOpt;
+
+ String documentation;
+ String simpleTypesString;
+ int duplicateIndex = -1;
+ int realIndex;
+ String contentQualifiedName;
+
+ public int compareTo(FieldDesc o) {
+ return name.compareTo(o.name);
+ }
+
+ public String toString() {
+ return "Field: " + name + ";" + type + ";" + elementName + ";" + elementType;
+ }
+
+}
diff --git a/plugins/devkit/src/dom/generator/FileManager.java b/plugins/devkit/src/dom/generator/FileManager.java
new file mode 100644
index 000000000000..8ad5c711a6c4
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/FileManager.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public interface FileManager {
+ public File releaseOutputFile(File outFile);
+ public File getOutputFile(File target);
+}
diff --git a/plugins/devkit/src/dom/generator/GenerateDomModelAction.java b/plugins/devkit/src/dom/generator/GenerateDomModelAction.java
new file mode 100644
index 000000000000..fb8efd87244c
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/GenerateDomModelAction.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.project.Project;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class GenerateDomModelAction extends AnAction {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
+ if (project != null) {
+ new DomGenDialog(project).show();
+ }
+ }
+}
diff --git a/plugins/devkit/src/dom/generator/JetBrainsEmitter.java b/plugins/devkit/src/dom/generator/JetBrainsEmitter.java
new file mode 100644
index 000000000000..bf3c3bc35565
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/JetBrainsEmitter.java
@@ -0,0 +1,679 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.*;
+
+/**
+ * @author Gregory.Shrago
+ * @author Konstantin Bulenkov
+ */
+public class JetBrainsEmitter implements Emitter {
+ static final boolean NOT_COMPARE_MODE = true; // compare mode: skip package decl & all comments/javadoc
+ static final boolean JB_OFF = false;
+ static final boolean REPLACE_TYPES_WITH_INTERFACES = true;
+ private String AUTHOR = null;
+
+
+ public void emit(FileManager fileManager, ModelDesc model, File outputRoot) {
+ final NamespaceDesc nsdDef = model.nsdMap.get("");
+ final Set<String> simpleTypes = new TreeSet<String>();
+ for (TypeDesc td : model.jtMap.values()) {
+ generateClass(fileManager, td, model, outputRoot, simpleTypes);
+ }
+// for (Iterator it = nsdMap.values().iterator(); it.hasNext(); ) {
+// NamespaceDesc nsd = (NamespaceDesc) it.next();
+// generateSuper(nsd, outputRoot);
+// generateHelper(nsd, jtMap, outputRoot);
+// }
+ generateSuper(fileManager, nsdDef, model, outputRoot);
+ generateHelper(fileManager, nsdDef, model, outputRoot);
+
+ Util.log("SimpleTypes log:");
+ for (String s : simpleTypes) {
+ Util.log(" " + s);
+ }
+ }
+
+ public void generateClass(FileManager fileManager, TypeDesc td, ModelDesc model, File outDir, Set<String> simpleTypes) {
+ final Map<String, TypeDesc> jtMap = model.jtMap;
+ final Map<String, NamespaceDesc> nsdMap = model.nsdMap;
+ final NamespaceDesc nsd = nsdMap.get(nsdMap.containsKey(td.xsNamespace) ? td.xsNamespace : "");
+ final String typeName = td.name;
+ final String typeQName = model.getNSDPrefix(td) + typeName;
+ final String pkgName = typeQName.lastIndexOf('.') > -1 ? typeQName.substring(0, typeQName.lastIndexOf('.')) : "";
+
+ final File outFile = fileManager.getOutputFile(new File(outDir, toJavaFileName(typeQName)));
+ PrintWriter out = null;
+ try {
+ TreeSet<String> externalClasses = new TreeSet<String>();
+ if (td.type != TypeDesc.TypeEnum.ENUM) {
+ if (nsd.imports != null) {
+ StringTokenizer st = new StringTokenizer(nsd.imports, ";");
+ while (st.hasMoreTokens()) {
+ externalClasses.add(st.nextToken());
+ }
+ }
+ if (!model.getNSDPrefix("", nsd.superClass, false).equals(model.getNSDPrefix(td))) {
+ externalClasses
+ .add(model.getNSDPrefix("", nsd.superClass, false) + nsd.superClass.substring(nsd.superClass.lastIndexOf(".") + 1));
+ }
+ if (td.supers != null) {
+ for (TypeDesc tds : td.supers) {
+ String pkg1 = model.getNSDPrefix(tds);
+ String pkg2 = model.getNSDPrefix(td);
+ if (!pkg1.equals(pkg2)) {
+ externalClasses.add(model.getNSDPrefix(tds) + tds.name);
+ }
+ }
+ }
+ for (FieldDesc fd : td.fdMap.values()) {
+ if (fd.simpleTypesString != null && fd.simpleTypesString.indexOf(":fully-qualified-classType;") != -1) {
+ externalClasses.add("com.intellij.psi.PsiClass");
+ }
+ if (fd.contentQualifiedName != null && fd.contentQualifiedName.indexOf('.') > 0) {
+ String pkgNameFD = fd.contentQualifiedName.substring(0, fd.contentQualifiedName.lastIndexOf('.'));
+ if (!pkgNameFD.equals(pkgName)) {
+ externalClasses.add(fd.contentQualifiedName);
+ }
+ }
+ if (fd.clType < 0) {
+ externalClasses.add("java.util.List");
+ }
+ externalClasses.add("org.jetbrains.annotations.NotNull");
+ externalClasses.add("com.intellij.util.xml.*");
+ }
+ }
+
+ Util.log("Generating type: " + typeName + "..");
+ out = new PrintWriter(new FileWriter(outFile));
+ if (NOT_COMPARE_MODE) {
+ out.println("// Generated on " + new Date());
+ out.println("// DTD/Schema : " + nsd.name);
+ }
+ out.println("");
+ if (NOT_COMPARE_MODE && pkgName != null && pkgName.length() > 0) {
+ out.println("package " + pkgName + ";");
+ }
+ out.println();
+ if (td.type != TypeDesc.TypeEnum.ENUM) {
+ boolean javaLang = false;
+ boolean external = false;
+ for (String s : externalClasses) {
+ if (s.startsWith("java.")) {
+ javaLang = true;
+ continue;
+ }
+ external = true;
+ out.println("import " + s + ";");
+ }
+ if (javaLang) {
+ if (external) out.println();
+ for (String s : externalClasses) {
+ if (!s.startsWith("java.")) continue;
+ out.println("import " + s + ";");
+ }
+ }
+ out.println();
+ }
+ if (td.type == TypeDesc.TypeEnum.ENUM) {
+ boolean text = false;
+ for (Map.Entry<String, FieldDesc> e : td.fdMap.entrySet()) {
+ if (!e.getKey().equals(e.getValue().name)) {
+ text = true;
+ break;
+ }
+ }
+ if (NOT_COMPARE_MODE) {
+ out.println(JDOC_OPEN);
+ out.println(JDOC_CONT + td.xsNamespace + ":" + td.xsName + " enumeration.");
+ if (AUTHOR != null) out.println(JDOC_CONT + AUTHOR);
+ printDocumentation(out, td.documentation, JDOC_CONT);
+
+ out.println(JDOC_CLOSE);
+ }
+ out.print("public enum " + typeName + (text ? (JB_OFF ? "" : " implements com.intellij.util.xml.NamedEnum") : ""));
+ out.print(" {");
+ boolean first = true;
+ for (Map.Entry<String, FieldDesc> e : td.fdMap.entrySet()) {
+ String val = e.getKey();
+ FieldDesc id = e.getValue();
+ if (first) {
+ first = false;
+ out.println("");
+ }
+ else {
+ out.println(",");
+ }
+ if (text) {
+ out.print("\t" + id.name + " (\"" + val + "\")");
+ }
+ else {
+ out.print("\t" + id.name);
+ }
+ }
+ if (text) {
+ out.println(";");
+ out.println();
+ out.println("\tprivate final String value;");
+ out.println("\tprivate " + typeName + "(String value) { this.value = value; }");
+ out.println("\tpublic String getValue() { return value; }");
+ }
+ out.println();
+ out.println("}");
+ return;
+ }
+ if (NOT_COMPARE_MODE) {
+ out.println(JDOC_OPEN);
+ if (td.type == TypeDesc.TypeEnum.GROUP_INTERFACE) {
+ out.println(JDOC_CONT + td.xsNamespace + ":" + td.xsName + " model group interface.");
+ }
+ else {
+ out.println(JDOC_CONT + td.xsNamespace + ":" + td.xsName + " interface.");
+ }
+ printDocumentation(out, td.documentation, JDOC_CONT);
+ if (AUTHOR != null) out.println(JDOC_CONT + AUTHOR);
+ out.println(JDOC_CLOSE);
+ }
+ out.print("public interface " + typeName);
+ if (nsd.superClass != null || (td.supers != null && td.supers.length > 1)) {
+ boolean comma = false;
+ if (td.type != TypeDesc.TypeEnum.GROUP_INTERFACE) {
+ if (nsd.superClass != null) {
+ out.print(" extends " + nsd.superClass.substring(nsd.superClass.lastIndexOf(".") + 1));
+ comma = true;
+ }
+ }
+ if (td.supers != null && td.supers.length > 0) {
+ if (!comma) out.print(" extends ");
+ for (TypeDesc aSuper : td.supers) {
+ if (comma) {
+ out.print(", ");
+ }
+ else {
+ comma = true;
+ }
+ out.print(aSuper.name);
+ }
+ }
+ }
+ out.println(" {");
+
+ FieldDesc[] fields = td.fdMap.values().toArray(new FieldDesc[td.fdMap.size()]);
+ if (fields.length == 0) {
+ Util.logwarn("no fields in: " + td.xsName);
+ }
+ Arrays.sort(fields, new Comparator<FieldDesc>() {
+ public int compare(FieldDesc o1, FieldDesc o2) {
+ return o1.realIndex - o2.realIndex;
+ }
+ });
+ out.println("");
+ for (FieldDesc field : fields) {
+ String tagName = field.tagName;
+ String type = field.type;
+ String elementType = field.elementType;
+ String name = field.name;
+ String paramName = toJavaIdName(field.clType > 0 ? name : field.elementName);
+ String javaDocTagName = field.clType < 0 ? tagName + " children" : tagName != null ? tagName + " child" : "simple content";
+ boolean isAttr = field.clType == FieldDesc.ATTR;
+ boolean isList = field.clType < 0;
+
+ if (name.equals("class")) { // getClass method prohibited
+ name = "clazz";
+ }
+ boolean nameChanged = field.tagName != null &&
+ !name
+ .equals(isList ? Util.pluralize(Util.toJavaFieldName(field.tagName)) : Util.toJavaFieldName(field.tagName));
+
+ // annotations
+ // types replacement
+ String newType = field.clType < 0 ? elementType : type;
+ String converterString = null;
+ if (field.simpleTypesString != null) {
+ if (field.simpleTypesString.indexOf(":fully-qualified-classType;") != -1) { // localType, remoteType, etc.
+ newType = "PsiClass";
+ //converterString = (JB_OFF ? "//" : "")+"\t@Convert (PsiClassReferenceConverter.class)";
+ }
+ else if (field.simpleTypesString.indexOf(":ejb-linkType;") != -1) {
+ }
+ else if (field.simpleTypesString.indexOf(":ejb-ref-nameType;") != -1) { // jndi-nameType
+ }
+ else if (field.simpleTypesString.indexOf(":pathType;") != -1) {
+ }
+ else if (field.simpleTypesString.indexOf(":java-identifierType;") != -1) {
+ //out.println((JB_OFF ? "//" : "") +"\t@Convert (JavaIdentifierConverter.class)");
+ }
+ else if (field.simpleTypesString.indexOf(":QName;") != -1) {
+ // ???
+ }
+ else if (field.simpleTypesString.indexOf(":integer;") != -1) { // BigDecimal
+ newType = REPLACE_TYPES_WITH_INTERFACES ? "Integer" : "int";
+ }
+ else if (field.simpleTypesString.indexOf(":int;") != -1) {
+ newType = REPLACE_TYPES_WITH_INTERFACES ? "Integer" : "int";
+ }
+ else if (field.simpleTypesString.indexOf(":byte;") != -1) {
+ newType = REPLACE_TYPES_WITH_INTERFACES ? "Byte" : "byte";
+ }
+ else if (field.simpleTypesString.indexOf(":short;") != -1) {
+ newType = REPLACE_TYPES_WITH_INTERFACES ? "Short" : "short";
+ }
+ else if (field.simpleTypesString.indexOf(":long;") != -1) {
+ newType = REPLACE_TYPES_WITH_INTERFACES ? "Long" : "long";
+ }
+ else if (field.simpleTypesString.indexOf(":float;") != -1) {
+ newType = REPLACE_TYPES_WITH_INTERFACES ? "Float" : "float";
+ }
+ else if (field.simpleTypesString.indexOf(":double;") != -1) {
+ newType = REPLACE_TYPES_WITH_INTERFACES ? "Double" : "double";
+ }
+ else if (field.simpleTypesString.indexOf(":boolean;") != -1) { // true-falseType
+ newType = REPLACE_TYPES_WITH_INTERFACES ? "Boolean" : "boolean";
+ }
+ for (int idx = 0; idx != -1;) {
+ simpleTypes.add(field.simpleTypesString.substring(idx));
+ idx = field.simpleTypesString.indexOf(';', idx) + 1;
+ if (idx == 0) break;
+ }
+ }
+ if (REPLACE_TYPES_WITH_INTERFACES) {
+ switch (Math.abs(field.clType)) {
+ case FieldDesc.ATTR:
+ newType = "GenericAttributeValue<" + newType + ">";
+ break;
+ case FieldDesc.BOOL:
+ newType = "GenericDomValue<Boolean>";
+ break;
+ case FieldDesc.SIMPLE:
+ break;
+ case FieldDesc.STR:
+ newType = "GenericDomValue<" + newType + ">";
+ break;
+ case FieldDesc.OBJ: {
+ TypeDesc ftd = jtMap.get(field.contentQualifiedName);
+ if (ftd != null && ftd.type == TypeDesc.TypeEnum.ENUM) {
+ newType = "GenericDomValue<" + ftd.name + ">";
+ }
+ break;
+ }
+ }
+ }
+ if (newType != null && isList) {
+ elementType = newType;
+ }
+ else if (newType != null) {
+ type = newType;
+ }
+ if (isList) {
+ type = "List<" + elementType + ">";
+ }
+
+ StringBuffer sbAnnotations = new StringBuffer();
+ if (field.clType == FieldDesc.SIMPLE) {
+ // sbAnnotations.append((JB_OFF ? "//" : "") +"\t@TagValue");
+ }
+ else if (isAttr && nameChanged) {
+ sbAnnotations.append((JB_OFF ? "//" : "") + "\t@Attribute (\"").append(tagName).append("\")");
+ }
+ else if (isList) {
+ // sbAnnotations.append((JB_OFF ? "//" : "") +"\t@SubTagList (\"" + tagName + "\")");
+ if (nameChanged) {
+ sbAnnotations.append((JB_OFF ? "//" : "") + "\t@SubTag (\"").append(tagName).append("\")");
+ }
+ else {
+ if (isBadTagName(tagName)) {
+ sbAnnotations.append((JB_OFF ? "//" : "") + "\t@SubTagList (\"").append(tagName).append("\")");
+ }
+ }
+ }
+ else {
+ if (field.duplicateIndex >= 0) {
+ sbAnnotations.append((JB_OFF ? "//" : "") + "\t@SubTag (value = \"").append(tagName).append("\", index = ")
+ .append(field.duplicateIndex - 1).append(")");
+ }
+ else if (field.clType == FieldDesc.BOOL) {
+ sbAnnotations.append((JB_OFF ? "//" : "") + "\t@SubTag (value = \"").append(tagName).append("\", indicator = true)");
+ }
+ else if (!name.equals(field.name)) {
+ sbAnnotations.append((JB_OFF ? "//" : "") + "\t@SubTag (\"").append(tagName).append("\")");
+ }
+ }
+ if (converterString != null) {
+ sbAnnotations.append("\n").append(converterString);
+ }
+ if (NOT_COMPARE_MODE && td.type != TypeDesc.TypeEnum.GROUP_INTERFACE) {
+ out.println("\t" + JDOC_OPEN);
+ final String text;
+ if (isList) {
+ text = "the list of " + javaDocTagName;
+ }
+ else {
+ text = "the value of the " + javaDocTagName;
+ }
+ out.println("\t" + JDOC_CONT + "Returns " + text + ".");
+ printDocumentation(out, field.documentation, "\t" + JDOC_CONT);
+ out.println("\t" + JDOC_CONT + "@return " + text + ".");
+ out.println("\t" + JDOC_CLOSE);
+ }
+ out.println((JB_OFF ? "//" : "") + "\t@NotNull");
+ if (td.type != TypeDesc.TypeEnum.GROUP_INTERFACE) {
+ if (sbAnnotations.length() > 0) out.println(sbAnnotations);
+ if (field.required) {
+ out.println((JB_OFF ? "//" : "") + "\t@Required");
+ }
+ }
+ out.print("\t");
+ //out.print("public ");
+ out.print(type);
+ out.print(" ");
+ out.print("get");
+ out.print(Util.capitalize(name));
+ out.println("();");
+
+ final boolean genAddRemoveInsteadOfSet = true;
+ if (!genAddRemoveInsteadOfSet || field.clType > 0) {
+ if (field.clType == FieldDesc.SIMPLE) {
+ if (NOT_COMPARE_MODE && td.type != TypeDesc.TypeEnum.GROUP_INTERFACE) {
+ out.println("\t" + JDOC_OPEN);
+ if (field.clType < 0) {
+ out.println("\t" + JDOC_CONT + "Sets the list of " + javaDocTagName + ".");
+ }
+ else {
+ out.println("\t" + JDOC_CONT + "Sets the value of the " + javaDocTagName + ".");
+ }
+ out.println("\t" + JDOC_CONT + "@param " + paramName + " the new value to set");
+ out.println("\t" + JDOC_CLOSE);
+ if (sbAnnotations.length() > 0) out.println(sbAnnotations);
+ }
+ out.print("\t");
+ //out.print("public ");
+ out.print("void set");
+ out.print(Util.capitalize(name));
+ out.print("(");
+ if (field.required) {
+ out.print((JB_OFF ? "" : "@NotNull "));
+ }
+ out.print(type);
+ out.print(" ");
+ out.print(paramName);
+ out.println(");");
+ }
+ }
+ else {
+ if (NOT_COMPARE_MODE && td.type != TypeDesc.TypeEnum.GROUP_INTERFACE) {
+ out.println("\t" + JDOC_OPEN);
+ out.println("\t" + JDOC_CONT + "Adds new child to the list of " + javaDocTagName + ".");
+ out.println("\t" + JDOC_CONT + "@return created child");
+ out.println("\t" + JDOC_CLOSE);
+ if (sbAnnotations.length() > 0) out.println(sbAnnotations);
+ }
+ out.print("\t");
+ //out.print("public ");
+ out.print(elementType + " add");
+ out.print(Util.capitalize(field.elementName));
+ out.println("();");
+ }
+
+ out.println("");
+ out.println("");
+ }
+ out.println("}");
+ }
+ catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ finally {
+ try {
+ out.close();
+ }
+ catch (Exception ex) {
+ }
+ fileManager.releaseOutputFile(outFile);
+ }
+ }
+
+ private static boolean isBadTagName(String tagName) {
+ if (Character.isUpperCase(tagName.charAt(0))) return false;
+ final char[] chars = tagName.toCharArray();
+ for (int i = 1; i < chars.length; i++) {
+ if (Character.isUpperCase(chars[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void generateSuper(FileManager fileManager, NamespaceDesc nsd, ModelDesc model, File outDir) {
+ if (nsd.superClass == null || nsd.superClass.length() == 0) return;
+ final String typeName = nsd.superClass.substring(nsd.superClass.lastIndexOf(".") + 1);
+ final String typeQName = model.toJavaQualifiedTypeName("", nsd.superClass, false);
+ String pkgName = typeQName.substring(0, typeQName.lastIndexOf('.'));
+ File outFile = new File(outDir, toJavaFileName(typeQName));
+ outFile = fileManager.getOutputFile(outFile);
+ PrintWriter out = null;
+ try {
+ Util.log("Generating type: " + typeName + "..");
+ out = new PrintWriter(new FileWriter(outFile));
+ out.println("// Generated on " + new Date());
+ out.println("// DTD/Schema : " + nsd.name);
+ out.println("");
+ if (pkgName != null) {
+ out.println("package " + pkgName + ";");
+ }
+ out.println("");
+ out.println("");
+ out.println(JDOC_OPEN);
+ out.println(JDOC_CONT + nsd.name + " base interface.");
+ if (AUTHOR != null) out.println(JDOC_CONT + AUTHOR);
+ out.println(JDOC_CLOSE);
+ out.print("public interface " + typeName + " ");
+ out.println("{");
+
+
+ out.println("}");
+ }
+ catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ finally {
+ try {
+ if (out != null) {
+ out.close();
+ }
+ }
+ catch (Exception ex) {
+ }
+ fileManager.releaseOutputFile(outFile);
+ }
+ }
+
+ private void generateHelper(FileManager fileManager, NamespaceDesc nsd, ModelDesc model, File outDir) {
+ final Map<String, TypeDesc> jtMap = model.jtMap;
+ final Map<String, NamespaceDesc> nsdMap = model.nsdMap;
+ if (nsd.helperClass == null || nsd.helperClass.length() == 0) return;
+ ArrayList<TypeDesc> jtList = new ArrayList<TypeDesc>();
+ for (TypeDesc td : jtMap.values()) {
+ if (td.type != TypeDesc.TypeEnum.CLASS) continue;
+// if (!nsd.name.equals(td.xsNamespace)) {
+// continue;
+// }
+ jtList.add(td);
+ }
+ if (jtList.size() == 0) return;
+
+ String typeName = nsd.helperClass.substring(nsd.helperClass.lastIndexOf(".") + 1);
+ final String typeQName = model.toJavaQualifiedTypeName("", nsd.helperClass, false);
+ String pkgName = typeQName.substring(0, typeQName.lastIndexOf('.'));
+ File outFile = new File(outDir, toJavaFileName(typeQName));
+ outFile = fileManager.getOutputFile(outFile);
+ PrintWriter out = null;
+ try {
+ Util.log("Generating type: " + typeName + "..");
+ out = new PrintWriter(new FileWriter(outFile));
+ out.println("// Generated on " + new Date());
+ out.println("// DTD/Schema : " + nsd.name);
+ out.println("");
+ if (pkgName != null) {
+ out.println("package " + pkgName + ";");
+ }
+ out.println("");
+ out.println("");
+ out.println(JDOC_OPEN);
+ out.println(JDOC_CONT + nsd.name + " helper class.");
+ if (AUTHOR != null) out.println(JDOC_CONT + AUTHOR);
+ out.println(JDOC_CLOSE);
+ out.print("public class " + typeName + " ");
+ out.println("{");
+ out.println("");
+ out.println("\tprivate interface GetName { String getName(Object o); }");
+ out.println("\tprivate static java.util.HashMap<Class, GetName> nameMap = new java.util.HashMap();");
+ out.println("\tstatic {");
+
+ for (TypeDesc td : jtList) {
+ ArrayList<FieldDesc> fields = new ArrayList<FieldDesc>(td.fdMap.values());
+ Collections.sort(fields, new Comparator<FieldDesc>() {
+ public int compare(FieldDesc o1, FieldDesc o2) {
+ return o1.realIndex - o2.realIndex;
+ }
+ });
+ int guessPriority = 0;
+ FieldDesc guessedField = null;
+ for (FieldDesc fd : fields) {
+ if (fd.clType == FieldDesc.STR || fd.clType == FieldDesc.SIMPLE || fd.clType == FieldDesc.ATTR) {
+ if (fd.name.equals("name") && guessPriority < 10) {
+ guessPriority = 10;
+ guessedField = fd;
+ }
+ else if (fd.name.endsWith("Name")) {
+ if ((fd.name.endsWith(Util.decapitalize(td.name + "Name")) || fd.realIndex < 2) && guessPriority < 10) {
+ guessPriority = 10;
+ guessedField = fd;
+ }
+ else if (fd.name.endsWith(Util.decapitalize("DisplayName")) && guessPriority < 5) {
+ guessPriority = 5;
+ guessedField = fd;
+ }
+ else if (guessPriority < 3) {
+ guessPriority = 3;
+ guessedField = fd;
+ }
+ }
+ else if (fd.name.equals("value") && guessPriority < 1) {
+ guessPriority = 1;
+ guessedField = fd;
+ }
+ }
+ else if ((fd.clType == -FieldDesc.OBJ || fd.clType == -FieldDesc.STR) && fd.name.endsWith("displayNames") && guessPriority < 5) {
+ guessPriority = 5;
+ guessedField = fd;
+ }
+ }
+ out.println();
+ String qname = model.getNSDPrefix(td) + td.name;
+ String tdNameString = "\"" + toPresentationName(td.name) + "\"";
+ out.println("\t\tnameMap.put(" + qname + ".class, new GetName() {");
+ out.println("\t\t\tpublic String getName(Object o) {");
+ if (guessedField != null) {
+ out.println("\t\t\t\t" + qname + " my = (" + qname + ") o;");
+ String getter = "my.get" + Util.capitalize(guessedField.name) + "()";
+ if (guessedField.clType > 0) {
+ out.println("\t\t\t\tString s = o==null? null:" + getter +
+ (guessedField.clType == FieldDesc.STR || guessedField.clType == FieldDesc.ATTR ? ".getValue();" : ";"));
+ out.println("\t\t\t\treturn s==null?" + tdNameString + ":s;");
+ }
+ else {
+ out.println("\t\t\t\treturn (o!=null && " + getter + "!=null && " + getter + ".size()>0)?");
+ out.println("\t\t\t\t\tgetPresentationName(" + getter + ".get(0), null):" + tdNameString + ";");
+ }
+ }
+ else {
+ out.println("\t\t\t\treturn " + tdNameString + ";");
+ }
+ out.println("\t\t\t}");
+ out.println("\t\t});");
+ }
+ out.println("\t}");
+
+ out.println("\tpublic static String getPresentationName(Object o, String def) {");
+ out.println("\t\tGetName g = o!=null? nameMap.get(o.getClass().getInterfaces()[0]):null;");
+ out.println("\t\treturn g != null?g.getName(o):def;");
+ out.println("\t}");
+ out.println("}");
+ }
+ catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ finally {
+ try {
+ out.close();
+ }
+ catch (Exception ex) {
+ }
+ fileManager.releaseOutputFile(outFile);
+ }
+ }
+
+ public static void printDocumentation(PrintWriter out, String str, String prefix) {
+ if (str == null) return;
+ StringTokenizer st = new StringTokenizer(str, "\n\r");
+ while (st.hasMoreTokens()) {
+ String line = prefix + st.nextToken();
+ out.println(line);
+ }
+ }
+
+ public static String toPresentationName(String typeName) {
+ StringBuffer sb = new StringBuffer(typeName.length() + 10);
+ boolean prevUp = true;
+ for (int i = 0; i < typeName.length(); i++) {
+ char c = typeName.charAt(i);
+ if (Character.isUpperCase(c) && !prevUp) {
+ sb.append(' ');
+ }
+ sb.append(c);
+ prevUp = Character.isUpperCase(c);
+ }
+ return sb.toString();
+ }
+
+ private static String toJavaFileName(String typeName) {
+ return typeName.replace('.', File.separatorChar) + ".java";
+ }
+
+ public static String toJavaIdName(String javaFieldName) {
+ if (Util.RESERVED_NAMES_MAP.containsKey(javaFieldName)) {
+ javaFieldName += "_";
+ }
+ return javaFieldName;
+ }
+
+
+ public void setAuthor(String author) {
+ AUTHOR = "@author " + author;
+ }
+}
diff --git a/plugins/devkit/src/dom/generator/Main.java b/plugins/devkit/src/dom/generator/Main.java
new file mode 100644
index 000000000000..e164a89dcbff
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/Main.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import java.io.File;
+
+/**
+ * @author Gregory.Shrago
+ * @author Konstantin Bulenkov
+ */
+public class Main {
+
+
+ public static void main(String argv[]) throws Exception {
+ if (argv.length != 4) {
+ System.out.println("Usage: Main <XSD or DTD> <input folder> <output folder> <config xml>");
+ }
+ String mode = argv[0];
+ final ModelLoader loader;
+ if (mode.equalsIgnoreCase("xsd")) {
+ loader = new XSDModelLoader();
+ }
+ else if (mode.equalsIgnoreCase("dtd")) {
+ loader = new DTDModelLoader();
+ }
+ else {
+ System.out.println("'"+mode+"' format not supported");
+ System.exit(-1);
+ return;
+ }
+ final File modelRoot = new File(argv[1]);
+ final File outputRoot = new File(argv[2]);
+ final File configXml = new File(argv[3]);
+
+ outputRoot.mkdirs();
+ final ModelGen modelGen = new ModelGen(loader);
+ modelGen.loadConfig(configXml);
+ modelGen.perform(outputRoot, modelRoot);
+ }
+
+}
diff --git a/plugins/devkit/src/dom/generator/MergingFileManager.java b/plugins/devkit/src/dom/generator/MergingFileManager.java
new file mode 100644
index 000000000000..1076eedb9d06
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/MergingFileManager.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import com.intellij.util.ArrayUtil;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.TreeSet;
+
+/**
+ * @author Gregory.Shrago
+ * @author Konstantin Bulenkov
+ */
+public class MergingFileManager implements FileManager {
+
+ public File getOutputFile(File target) {
+ File outFile = target;
+ if (!outFile.getParentFile().exists() && !outFile.getParentFile().mkdirs()) {
+ Util.logerr("parent mkdirs failed: " + outFile);
+ return null;
+ }
+ for (int i = 0; outFile.exists(); i++) {
+ outFile = new File(target.getParentFile(), target.getName() + ".tmp." + i);
+ }
+ return outFile;
+ }
+
+ public File releaseOutputFile(File outFile) {
+ int idx = outFile.getName().indexOf(".tmp.");
+ File target = outFile;
+ if (idx > -1) {
+ target = new File(outFile.getParentFile(), outFile.getName().substring(0, idx));
+ String[] curLines = loadFile(outFile);
+ String[] prevLines = loadFile(target);
+ String[] mergedLines = mergeLines(curLines, prevLines);
+ if (mergedLines != prevLines) {
+ if (mergedLines == curLines) {
+ if (target.exists() && !target.delete()) {
+ Util.logerr("file replace failed: " + target);
+ outFile.delete();
+ } else {
+ outFile.renameTo(target);
+ Util.logwarn("file replaced: " + target);
+ }
+ } else {
+ outFile.delete();
+ if (target.exists() && !target.delete()) {
+ Util.logerr("file replace failed: " + target);
+ } else {
+ writeFile(target, mergedLines);
+ Util.logwarn("file merged: " + target);
+ }
+ }
+ } else {
+ outFile.delete();
+ }
+ }
+ return target;
+ }
+
+ private static String[] mergeLines(String[] curLines, String[] prevLines) {
+ if (prevLines.length == 0) return curLines;
+ ArrayList<String> merged = new ArrayList<String>();
+ int curIdx = 0, prevIdx = 0;
+ String cur, prev;
+ boolean classScope = false;
+ boolean importMerged = false;
+ for (int i = 0; i < Math.max(curLines.length, prevLines.length); i++) {
+ cur = curIdx < curLines.length ? curLines[curIdx] : "";
+ prev = prevIdx < prevLines.length ? prevLines[prevIdx] : "";
+ if (classScope) {
+ merged.addAll(Arrays.asList(curLines).subList(curIdx, curLines.length));
+ break;
+ } else if (prev.trim().startsWith("import ") || cur.trim().startsWith("import ")) {
+ if (importMerged) continue;
+ importMerged = true;
+ int[] indices = new int[]{curIdx, prevIdx};
+ mergeImports(merged, curLines, prevLines, indices);
+ curIdx = indices[0];
+ prevIdx = indices[1];
+ } else if (cur.equals(prev)) {
+ if (cur.trim().startsWith("public interface ")
+ || cur.trim().startsWith("public enum ")) classScope = true;
+ merged.add(cur);
+ curIdx++;
+ prevIdx++;
+ } else if (prev.trim().startsWith("@")) {
+ merged.add(prev);
+ prevIdx++;
+ } else if (cur.trim().startsWith("@")) {
+ merged.add(cur);
+ curIdx++;
+ } else if (cur.trim().startsWith("package ") && prev.trim().startsWith("package ")) {
+ merged.add(prev);
+ curIdx++;
+ prevIdx++;
+ } else if (cur.trim().startsWith("public interface ") && prev.trim().startsWith("public interface ")) {
+ classScope = true;
+ prevIdx = addAllStringsUpTo(merged, prevLines, prevIdx, "{");
+ curIdx = addAllStringsUpTo(null, curLines, curIdx, "{");
+ } else if (cur.trim().startsWith("* ")) {
+ curIdx = addAllStringsUpTo(merged, curLines, curIdx, "*/");
+ if (prev.trim().startsWith("* ") || prev.trim().endsWith("*/")) {
+ prevIdx = addAllStringsUpTo(null, prevLines, prevIdx, "*/");
+ }
+ } else {
+ merged.add(cur);
+ curIdx++;
+ prevIdx++;
+ }
+ }
+ String[] mergedLines = ArrayUtil.toStringArray(merged);
+ if (compareLines(mergedLines, prevLines, 2) == 0) {
+ return prevLines;
+ } else if (compareLines(mergedLines, curLines, 2) == 0) {
+ return curLines;
+ } else {
+ return mergedLines;
+ }
+ }
+
+ private static void mergeImports(ArrayList<String> merged, String[] curLines, String[] prevLines, int[] indices) {
+ TreeSet<String> externalClasses = new TreeSet<String>();
+ for (int i = 0; i < curLines.length; i++) {
+ String line = curLines[i].trim();
+ if (line.startsWith("import ") && line.endsWith(";")) {
+ indices[0] = i + 1;
+ final String name = line.substring("import ".length(), line.length() - 1).trim();
+ if (name.endsWith("*")) continue;
+ externalClasses.add(name);
+ }
+ }
+ for (int i = 0; i < prevLines.length; i++) {
+ String line = prevLines[i].trim();
+ if (line.startsWith("import ") && line.endsWith(";")) {
+ indices[1] = i + 1;
+ final String name = line.substring("import ".length(), line.length() - 1).trim();
+ if (name.endsWith("*")) continue;
+ externalClasses.add(name);
+ }
+ }
+ boolean javaLang = false;
+ for (String s : externalClasses) {
+ if (s.startsWith("java.")) {
+ javaLang = true;
+ continue;
+ }
+ merged.add("import " + s + ";");
+ }
+ if (javaLang) {
+ merged.add("");
+ for (String s : externalClasses) {
+ if (!s.startsWith("java.")) continue;
+ merged.add("import " + s + ";");
+ }
+ }
+ }
+
+ private static int addAllStringsUpTo(ArrayList<String> merged, String[] lines, int startIdx, String upTo) {
+ String str;
+ do {
+ str = startIdx < lines.length ? lines[startIdx] : upTo;
+ if (merged != null) merged.add(str);
+ startIdx++;
+ } while (!str.trim().endsWith(upTo) && startIdx < lines.length);
+ return startIdx;
+ }
+
+ private static int compareLines(String[] mergedLines, String[] curLines, int start) {
+ if (mergedLines.length < curLines.length) return -1;
+ if (mergedLines.length > curLines.length) return 1;
+ for (int i = start; i < mergedLines.length; i++) {
+ final int comp = mergedLines[i].compareTo(curLines[i]);
+ if (comp != 0) return comp;
+ }
+ return 0;
+ }
+
+
+ private static void writeFile(File target, String[] mergedLines) {
+ PrintWriter out = null;
+ try {
+ int lineCount = mergedLines.length;
+ while (lineCount > 0 && mergedLines[lineCount - 1].length() == 0) lineCount--;
+ out = new PrintWriter(new FileWriter(target));
+ for (int i = 0; i < lineCount; i++) {
+ String mergedLine = mergedLines[i];
+ out.println(mergedLine);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+
+ private static String[] loadFile(File f1) {
+ if (!f1.exists()) return ArrayUtil.EMPTY_STRING_ARRAY;
+ ArrayList<String> list = new ArrayList<String>();
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new FileReader(f1));
+ String str;
+ while ((str = in.readLine()) != null) {
+ list.add(str);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ return ArrayUtil.toStringArray(list);
+ }
+
+}
diff --git a/plugins/devkit/src/dom/generator/ModelDesc.java b/plugins/devkit/src/dom/generator/ModelDesc.java
new file mode 100644
index 000000000000..e940fd24b733
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/ModelDesc.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import org.apache.xerces.xs.XSObject;
+
+import javax.xml.namespace.QName;
+import java.io.PrintWriter;
+import java.util.*;
+
+/**
+ * @author Gregory.Shrago
+ * @author Konstantin Bulenkov
+ */
+public class ModelDesc {
+ final Map<String, String> name2replaceMap = new HashMap<String, String>();
+ final Map<QName, String> qname2FileMap = new HashMap<QName, String>();
+ final Map<String, NamespaceDesc> nsdMap = new HashMap<String, NamespaceDesc>();
+ final Map<String, TypeDesc> jtMap = new TreeMap<String, TypeDesc>();
+
+
+ public String getNSDPrefix(TypeDesc td) {
+ return getNSDPrefix(td.xsNamespace, td.name, td.type == TypeDesc.TypeEnum.ENUM);
+ }
+
+ public String getNSDPrefix(String namespace, String name, boolean isEnum) {
+ final int lastIdx = name.lastIndexOf(".");
+ if (lastIdx > -1) return name.substring(0, lastIdx + 1);
+ final NamespaceDesc nsd = getNSD(namespace);
+ if (isEnum && nsd.enumPkg != null) {
+ return nsd.enumPkg + ".";
+ }
+ if (nsd.pkgNames != null) {
+ final QName qname = new QName(namespace, name);
+ final String files = qname2FileMap.get(qname);
+ if (files != null) {
+ for (int i = 0; i < nsd.pkgNames.length; i += 2) {
+ String file = nsd.pkgNames[i];
+ String pkg = nsd.pkgNames[i + 1];
+ if (files.contains(":" + file + ":")) {
+ return pkg + ".";
+ }
+ }
+ }
+ }
+ return nsd.pkgName != null && nsd.pkgName.length() > 0 ? nsd.pkgName + "." : "";
+ }
+
+ public NamespaceDesc getNSD(String namespace) {
+ NamespaceDesc nsd = nsdMap.get(namespace);
+ if (nsd == null) {
+ nsd = nsdMap.get("");
+ }
+ return nsd;
+ }
+
+
+ public String toJavaTypeName(String tname, String ns) {
+ final int lastIndex = tname.lastIndexOf('.');
+ String xmlName = lastIndex>-1? tname.substring(lastIndex+1): tname;
+ NamespaceDesc nsd = getNSD(ns);
+ if (ns == null || !ns.endsWith(".dtd")) {
+ if (xmlName.endsWith(Util.ANONYMOUS_ELEM_TYPE_SUFFIX)) xmlName = xmlName.substring(0, xmlName.length() - Util.ANONYMOUS_ELEM_TYPE_SUFFIX.length());
+ else if (xmlName.endsWith(Util.ANONYMOUS_ATTR_TYPE_SUFFIX)) xmlName = xmlName.substring(0, xmlName.length() - Util.ANONYMOUS_ATTR_TYPE_SUFFIX.length());
+ else if (xmlName.endsWith(Util.TYPE_SUFFIX)) xmlName = xmlName.substring(0, xmlName.length() - Util.TYPE_SUFFIX.length());
+ }
+ String rc = Util.capitalize(Util.toJavaName(xmlName));
+ if (nsd.prefix != null && nsd.prefix.length()>0 && !rc.startsWith(nsd.prefix)) {
+ rc = nsd.prefix + rc;
+ }
+ if (Util.RESERVED_NAMES_MAP.containsKey(rc)) {
+ rc = Util.RESERVED_NAMES_MAP.get(rc);
+ }
+ if (name2replaceMap.containsKey(rc)) {
+ rc = Util.expandProperties(name2replaceMap.get(rc), nsd.props);
+ }
+
+ return rc;
+ }
+
+ public String toJavaQualifiedTypeName(XSObject xs, Map<String, NamespaceDesc> nsdMap, boolean isEnum) {
+ String typeName = toJavaTypeName(xs.getName(), xs.getNamespace());
+ return getNSDPrefix(xs.getNamespace(), xs.getName(), isEnum) + typeName;
+ }
+
+ public String toJavaQualifiedTypeName(String namespace, String xmlname, boolean isEnum) {
+ return getNSDPrefix(namespace, xmlname, isEnum) + toJavaTypeName(xmlname, namespace);
+ }
+
+ void dump(final PrintWriter out) {
+// out.println("-- qname2FileMap ---");
+// out.println(qname2FileMap);
+ out.println("-- nsdMap ---");
+ for (Map.Entry<String, NamespaceDesc> entry : nsdMap.entrySet()) {
+ out.println("namespace key: "+entry.getKey());
+ dumpNamespace(entry.getValue(), out);
+ }
+ out.println("-- jtMap ---");
+ for (Map.Entry<String, TypeDesc> entry : jtMap.entrySet()) {
+ out.println("type key: "+entry.getKey());
+ dumpTypeDesc(entry.getValue(), out);
+ }
+ }
+
+ private void dumpTypeDesc(TypeDesc td, PrintWriter out) {
+ final ArrayList<String> superList;
+ if (td.supers !=null) {
+ superList = new ArrayList<String>();
+ for (TypeDesc aSuper : td.supers) {
+ superList.add(getNSDPrefix(aSuper)+aSuper.name);
+ }
+ } else superList = null;
+ out.println(" name " + td.name);
+ out.println(" type " + td.type);
+ out.println(" xsName " + td.xsName);
+ out.println(" xsNS " + td.xsNamespace);
+ out.println(" dups " + td.duplicates);
+ out.println(" supers " + (superList!=null?superList:"null"));
+ out.println(" doc " + (td.documentation != null ? td.documentation.length() : "null"));
+ for (Map.Entry<String, FieldDesc> entry : td.fdMap.entrySet()) {
+ out.println(" field key: " + entry.getKey());
+ dumpFieldDesc(td, entry.getValue(), out);
+ }
+ }
+
+ private void dumpFieldDesc(TypeDesc td, FieldDesc fd, PrintWriter out) {
+ out.println(" name " + fd.name);
+ if (td.type == TypeDesc.TypeEnum.ENUM) return;
+ out.println(" clType " + fd.clType);
+ out.println(" required " + fd.required);
+ out.println(" index " + fd.idx+"/"+fd.realIndex);
+ out.println(" choiceOpt " + fd.choiceOpt);
+ out.println(" choice " + (fd.choice!=null?fd.choice.length:"null"));
+ out.println(" content " + fd.contentQualifiedName);
+ out.println(" dupIdx " + fd.duplicateIndex);
+ out.println(" elName " + fd.elementName);
+ out.println(" elType " + fd.elementType);
+ out.println(" def " + fd.def);
+ out.println(" doc " + (fd.documentation != null? fd.documentation.length(): "null"));
+ }
+
+ private void dumpNamespace(NamespaceDesc value, PrintWriter out) {
+ if (value.skip) return;
+ out.println(" name "+value.name);
+ out.println(" prefix "+value.prefix);
+ out.println(" pkgName "+value.pkgName);
+ out.println(" pkgNames "+(value.pkgNames != null?Arrays.asList(value.pkgNames):"null"));
+ out.println(" enumPkg "+value.enumPkg);
+ out.println(" super "+value.superClass);
+ }
+}
diff --git a/plugins/devkit/src/dom/generator/ModelGen.java b/plugins/devkit/src/dom/generator/ModelGen.java
new file mode 100644
index 000000000000..8f1f709a6906
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/ModelGen.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.apache.xerces.xni.XMLResourceIdentifier;
+import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import java.io.CharArrayReader;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Gregory.Shrago
+ * @author Konstantin Bulenkov
+ */
+public class ModelGen {
+ private final ModelDesc model = new ModelDesc();
+ private final Map<String, String> schemaLocationMap = new HashMap<String, String>();
+ private final ModelLoader loader;
+ private final Emitter emitter;
+ private final FileManager fileManager;
+
+
+ public ModelGen(ModelLoader loader) {
+ this(loader, new JetBrainsEmitter(), new MergingFileManager());
+ }
+
+ public ModelGen(ModelLoader loader, Emitter emitter, FileManager fileManager) {
+ this.loader = loader;
+ this.emitter = emitter;
+ this.fileManager = fileManager;
+ }
+
+ public ModelDesc getModel() {
+ return model;
+ }
+
+ public static Element loadXml(File configXml) throws Exception {
+ SAXBuilder saxBuilder = new SAXBuilder();
+ saxBuilder.setEntityResolver(new EntityResolver() {
+ public InputSource resolveEntity(String publicId,
+ String systemId)
+ throws SAXException, IOException {
+ return new InputSource(new CharArrayReader(new char[0]));
+ }
+ });
+ final Document document = saxBuilder.build(configXml);
+ return document.getRootElement();
+ }
+
+ public void loadConfig(File configXml) throws Exception {
+ loadConfig(loadXml(configXml));
+ }
+
+ public void setConfig(String schema, String location, NamespaceDesc desc, String... schemasToSkip) {
+ schemaLocationMap.put(schema, location);
+ for (String sch : schemasToSkip) {
+ if (sch != null && sch.length() > 0) {
+ model.nsdMap.put(sch, new NamespaceDesc(sch));
+ }
+ }
+ model.nsdMap.put("", new NamespaceDesc("", "", "com.intellij.util.xml.DomElement", "", null, null, null, null));
+ model.nsdMap.put(desc.name, desc);
+ }
+
+ public void loadConfig(Element element) {
+ final Element namespaceEl = element.getChild("namespaces");
+ for (Element e : (List<Element>) namespaceEl.getChildren("schemaLocation")) {
+ final String name = e.getAttributeValue("name");
+ final String file = e.getAttributeValue("file");
+ schemaLocationMap.put(name, file);
+ }
+ for (Element e : (List<Element>) namespaceEl.getChildren("reserved-name")) {
+ final String name = e.getAttributeValue("name");
+ final String replacement = e.getAttributeValue("replace-with");
+ model.name2replaceMap.put(name, replacement);
+ }
+ NamespaceDesc def = new NamespaceDesc("", "generated", "java.lang.Object", "", null, null, null, null);
+ for (Element nsElement : (List<Element>) namespaceEl.getChildren("namespace")) {
+ final String name = nsElement.getAttributeValue("name");
+ final NamespaceDesc nsDesc = new NamespaceDesc(name, def);
+
+ final String skip = nsElement.getAttributeValue("skip");
+ final String prefix = nsElement.getAttributeValue("prefix");
+ final String superC = nsElement.getAttributeValue("super");
+ final String imports = nsElement.getAttributeValue("imports");
+ final String packageS = nsElement.getAttributeValue("package");
+ final String packageEnumS = nsElement.getAttributeValue("enums");
+ final String interfaces = nsElement.getAttributeValue("interfaces");
+ final ArrayList<String> list = new ArrayList<String>();
+ for (Element pkgElement : (List<Element>) nsElement.getChildren("package")) {
+ final String pkgName = pkgElement.getAttributeValue("name");
+ final String fileName = pkgElement.getAttributeValue("file");
+ list.add(fileName);
+ list.add(pkgName);
+ }
+ for (Element pkgElement : (List<Element>) nsElement.getChildren("property")) {
+ final String propertyName = pkgElement.getAttributeValue("name");
+ final String propertyValue = pkgElement.getAttributeValue("value");
+ nsDesc.props.put(propertyName, propertyValue);
+ }
+
+ if (skip != null) nsDesc.skip = skip.equalsIgnoreCase("true");
+ if (prefix != null) nsDesc.prefix = prefix;
+ if (superC != null) nsDesc.superClass = superC;
+ if (imports != null) nsDesc.imports = imports;
+ if (packageS != null) nsDesc.pkgName = packageS;
+ if (packageEnumS != null) nsDesc.enumPkg = packageEnumS;
+ if (interfaces != null) nsDesc.intfs = interfaces;
+ if (!list.isEmpty()) nsDesc.pkgNames = ArrayUtil.toStringArray(list);
+ if (name.length() == 0) def = nsDesc;
+ model.nsdMap.put(name, nsDesc);
+ }
+ }
+
+ public void perform(final File outputRoot, final File... modelRoots) throws Exception {
+ loadModel(modelRoots);
+ emitter.emit(fileManager, model, outputRoot);
+
+ Util.log("Done.");
+ }
+
+ public void loadModel(final File... modelRoots) throws Exception {
+ XMLEntityResolver resolver = new XMLEntityResolver() {
+ public XMLInputSource resolveEntity(XMLResourceIdentifier xmlResourceIdentifier) throws XNIException, IOException {
+ String esid = xmlResourceIdentifier.getExpandedSystemId();
+ if (esid == null) {
+ final String location = schemaLocationMap.get(xmlResourceIdentifier.getNamespace());
+ if (location != null) {
+ esid = location;
+ } else {
+ return null;
+ }
+ }
+ // Util.log("resolving "+esid);
+ File f = null;
+ for (File root : modelRoots) {
+ if (root == null) continue;
+ if (root.isDirectory()) {
+ final String fileName = esid.substring(esid.lastIndexOf('/') + 1);
+ f = new File(root, fileName);
+ } else {
+ f = root;
+ }
+ }
+ if (f == null || !f.exists()) {
+ Util.logerr("unable to resolve: " + esid);
+ return null;
+ }
+ esid = f.getPath();
+ return new XMLInputSource(null, esid, null);
+ }
+ };
+ ArrayList<File> files = new ArrayList<File>();
+ for (File root : modelRoots) {
+ ContainerUtil.addAll(files, root.listFiles());
+ }
+ loader.loadModel(model, files, resolver);
+ Util.log(model.jtMap.size() + " java types loaded");
+ }
+
+}
diff --git a/plugins/devkit/src/dom/generator/ModelLoader.java b/plugins/devkit/src/dom/generator/ModelLoader.java
new file mode 100644
index 000000000000..cf71534b473d
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/ModelLoader.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+
+import java.io.File;
+import java.util.Collection;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public interface ModelLoader {
+ void loadModel(ModelDesc model, Collection<File> files, XMLEntityResolver resolver) throws Exception;
+}
diff --git a/plugins/devkit/src/dom/generator/NamespaceDesc.java b/plugins/devkit/src/dom/generator/NamespaceDesc.java
new file mode 100644
index 000000000000..f73d16ad2cee
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/NamespaceDesc.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class NamespaceDesc {
+ public NamespaceDesc(String name,
+ String pkgName,
+ String superClass,
+ String prefix,
+ String factoryClass,
+ String helperClass,
+ String imports,
+ String intfs) {
+ this.name = name;
+ this.pkgName = pkgName;
+ this.superClass = superClass;
+ this.prefix = prefix;
+ this.factoryClass = factoryClass;
+ this.helperClass = helperClass;
+ this.imports = imports;
+ this.intfs = intfs;
+ }
+
+ public NamespaceDesc(String name) {
+ this(name, "generated", "java.lang.Object", "", null, null, null, null);
+ skip = true;
+ }
+
+
+ public NamespaceDesc(String name, NamespaceDesc def) {
+ this.name = name;
+ this.pkgName = def.pkgName;
+ this.superClass = def.superClass;
+ this.prefix = def.prefix;
+ this.factoryClass = def.factoryClass;
+ this.helperClass = def.helperClass;
+ this.imports = def.imports;
+ this.intfs = def.intfs;
+ }
+
+ final Map<String, String> props = new HashMap<String, String>();
+ final String name;
+ String pkgName;
+ String superClass;
+ String prefix;
+ String factoryClass;
+ String helperClass;
+ String imports;
+ String intfs;
+ boolean skip;
+ String[] pkgNames;
+ String enumPkg;
+
+
+ public String toString() {
+ return "NS:"+name+" "+(skip?"skip":"")+pkgName;
+ }
+}
diff --git a/plugins/devkit/src/dom/generator/TypeDesc.java b/plugins/devkit/src/dom/generator/TypeDesc.java
new file mode 100644
index 000000000000..c644fd73124a
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/TypeDesc.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class TypeDesc {
+ public enum TypeEnum {
+ CLASS, ENUM, GROUP_INTERFACE
+ }
+
+ public TypeDesc(String xsName, String xsNamespace, String name, TypeEnum type) {
+ this.xsName = xsName;
+ this.xsNamespace = xsNamespace;
+ this.name = name;
+ this.type = type;
+ }
+
+ TypeEnum type;
+ final String xsName;
+ final String xsNamespace;
+ final String name;
+ final Map<String, FieldDesc> fdMap = new TreeMap<String, FieldDesc>();
+ boolean duplicates;
+ String documentation;
+ TypeDesc[] supers;
+
+ public String toString() {
+ return (type == TypeEnum.ENUM ? "enum" : "type") + ": " + name + ";" + xsName + ";";
+ }
+}
diff --git a/plugins/devkit/src/dom/generator/Util.java b/plugins/devkit/src/dom/generator/Util.java
new file mode 100644
index 000000000000..a393bb143602
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/Util.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import org.apache.xerces.xs.XSObject;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class Util {
+ public static final String ANONYMOUS_ELEM_TYPE_SUFFIX = "ElemType";
+ public static final String ANONYMOUS_ATTR_TYPE_SUFFIX = "AttrType";
+ public static final String TYPE_SUFFIX = "Type";
+
+ //
+ // Constants
+ //
+ public static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
+
+ // reserved names map
+ public static final String[] RESERVED_NAMES_TABLE = {
+ "abstract", "default", "if", "private", "this",
+ "boolean", "do", "implements", "protected", "throw",
+ "break", "double", "import", "public", "throws",
+ "byte", "else", "instanceof", "return", "transient",
+ "case", "extends", "int", "short", "try",
+ "catch", "final", "interface", "static", "void",
+ "char", "finally", "long", "strictfp", "volatile",
+ "class", "float", "native", "super", "while",
+ "const", "for", "new", "switch",
+ "continue", "goto", "package", "synchronized"
+ };
+ public static final HashMap<String, String> RESERVED_NAMES_MAP;
+
+ static {
+ RESERVED_NAMES_MAP = new HashMap<String, String>();
+ for (String aRESERVED_NAMES_TABLE : RESERVED_NAMES_TABLE) {
+ // RESERVED_NAMES_MAP.put(RESERVED_NAMES_TABLE[i], RESERVED_NAMES_TABLE[i]+"_");
+ // as far as there is no actual field but setters/getters:
+ RESERVED_NAMES_MAP.put(aRESERVED_NAMES_TABLE, aRESERVED_NAMES_TABLE);
+ }
+ //RESERVED_NAMES_MAP.put("class", "clazz");
+ }
+
+
+ static void log(String str) {
+ System.out.println(str);
+ }
+
+ static void logwarn(String str) {
+ System.out.println("[warn] " + str);
+ }
+
+ static void logerr(String str) {
+ System.out.println("[error] " + str);
+ }
+
+ public static String pluralize(String suggestion) {
+ // return suggestion+"List";
+ final String VOWELS = "aeiouy";
+ if (suggestion.endsWith("s") || suggestion.endsWith("x") ||
+ suggestion.endsWith("ch")) {
+ suggestion += "es";
+ } else {
+ int len = suggestion.length();
+ if (suggestion.endsWith("y") && len > 1 && VOWELS.indexOf(suggestion.charAt(len - 2)) < 0) {
+ suggestion = suggestion.substring(0, len - 1) + "ies";
+ } else {
+ suggestion += "s";
+ }
+ }
+ return suggestion;
+ }
+
+ public static String toJavaFieldName(String xmlName) {
+ String rc = toJavaName(xmlName);
+ if (RESERVED_NAMES_MAP.containsKey(rc)) {
+ rc = RESERVED_NAMES_MAP.get(rc);
+ }
+ return rc;
+ }
+
+
+ public static String computeEnumConstantName(String val, String typeName) {
+ String id = val;
+ for (int i = 1; i < id.length(); i++) {
+ if (Character.isUpperCase(id.charAt(i))
+ && Character.isLowerCase(id.charAt(i - 1))) {
+ id = id.substring(0, i) + "_" + id.substring(i);
+ i++;
+ }
+ }
+ id = id.toUpperCase();
+ id = id.replace('.', '_').replace('-', '_');
+ if (id.length() < 2 || !Character.isJavaIdentifierStart(id.charAt(0))) {
+ id = typeName + "_" + id;
+ }
+ return id;
+ }
+
+
+ public static String capitalize(String str) {
+ return Character.toUpperCase(str.charAt(0)) + str.substring(1);
+ }
+
+ public static String decapitalize(String str) {
+ return Character.toLowerCase(str.charAt(0)) + str.substring(1);
+ }
+
+ public static String toJavaName(String xmlName) {
+ xmlName = xmlName.substring(xmlName.lastIndexOf(':') + 1);
+ StringTokenizer st = new StringTokenizer(xmlName, "-");
+ StringBuffer sb = new StringBuffer(st.nextToken());
+ while (st.hasMoreTokens()) {
+ sb.append(capitalize(st.nextToken()));
+ }
+ return sb.toString();
+ }
+
+ public static String toDefXmlTagName(XSObject xs) {
+ String xmlName = xs.getName();
+ if (xmlName.endsWith(TYPE_SUFFIX)) xmlName = xmlName.substring(0, xmlName.length() - 4);
+ return xmlName;
+ }
+
+ public static String toDefXmlTagName(String tname) {
+ String xmlName = tname;
+ if (xmlName.endsWith(TYPE_SUFFIX)) xmlName = xmlName.substring(0, xmlName.length() - TYPE_SUFFIX.length());
+ return xmlName;
+ }
+
+
+ public static boolean addToNameMap(Map<String, FieldDesc> fdMap, FieldDesc fd1, boolean merge) {
+ boolean duplicates = false;
+ FieldDesc fd2;
+ if ((fd2 = fdMap.remove(fd1.name)) != null) {
+ if (fd2.clType == FieldDesc.ATTR) {
+ // attr <-> field
+ fd2.name = fd1.name + "Attr";
+ fdMap.put(fd2.name, fd2);
+ } else if (merge) {
+ fdMap.put(fd2.name, fd2);
+ return false;
+ } else {
+ duplicates = true;
+ fd2.name = fd1.name + "1";
+ fd2.duplicateIndex = 1;
+ fdMap.put(fd2.name, fd2);
+ fd1.name = fd1.name + "2";
+ fd1.duplicateIndex = 2;
+ }
+ } else if ((fd2 = fdMap.get(fd1.name + "1")) != null) {
+ int id = 2;
+ while (fdMap.containsKey(fd1.name + id)) id++;
+ fd1.name = fd1.name + id;
+ fd1.duplicateIndex = id;
+ }
+ fdMap.put(fd1.name, fd1);
+ return duplicates;
+ }
+
+ public static String expandProperties(final String str, final Map<String, String> map) {
+ if (str.indexOf("${") == -1) return str;
+ int state = 0;
+ final StringBuilder result = new StringBuilder();
+ final StringBuilder variable = new StringBuilder();
+ for (int i=0; i<str.length(); i++) {
+ final char ch = str.charAt(i);
+ switch (state) {
+ case 0:
+ if (ch == '$') state = 1;
+ else result.append(ch);
+ break;
+ case 1:
+ if (ch == '{') {
+ state = 2;
+ variable.setLength(0);
+ }
+ else {
+ state = 0;
+ result.append('$').append(ch);
+ }
+ break;
+ case 2:
+ if (ch == '}') {
+ final String value = map.get(variable.toString());
+ result.append(value == null? variable : value);
+ state = 0;
+ }
+ else {
+ variable.append(ch);
+ }
+ break;
+ }
+ }
+ return result.toString();
+ }
+}
+
diff --git a/plugins/devkit/src/dom/generator/XSDModelLoader.java b/plugins/devkit/src/dom/generator/XSDModelLoader.java
new file mode 100644
index 000000000000..b3e25e0dbaf6
--- /dev/null
+++ b/plugins/devkit/src/dom/generator/XSDModelLoader.java
@@ -0,0 +1,681 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * XSD/DTD Model generator tool
+ *
+ * By Gregory Shrago
+ * 2002 - 2006
+ */
+package org.jetbrains.idea.devkit.dom.generator;
+
+import org.apache.xerces.xs.*;
+import org.apache.xerces.impl.xs.XSComplexTypeDecl;
+import org.apache.xerces.impl.xs.XSParticleDecl;
+import org.apache.xerces.impl.xs.XSAttributeGroupDecl;
+import org.apache.xerces.impl.xs.XSElementDecl;
+import org.apache.xerces.impl.xs.util.XSObjectListImpl;
+import org.apache.xerces.impl.dv.XSSimpleType;
+import org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl;
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMErrorHandler;
+import org.w3c.dom.DOMError;
+import org.w3c.dom.TypeInfo;
+
+import javax.xml.namespace.QName;
+import java.io.File;
+import java.util.*;
+
+/**
+ * @author Gregory.Shrago
+ * @author Konstantin Bulenkov
+ */
+public class XSDModelLoader implements ModelLoader {
+ private static final boolean TEXT_ELEMENTS_ARE_COMPLEX = false;
+
+
+ private ModelDesc model;
+
+ public void loadModel(ModelDesc model, Collection<File> files, XMLEntityResolver resolver) throws Exception {
+ this.model = model;
+ processSchemas(files, resolver);
+ }
+
+ public static boolean checkComplexType(XSTypeDefinition td) {
+ if (td.getTypeCategory() != XSTypeDefinition.COMPLEX_TYPE) return false;
+ XSComplexTypeDefinition ctd = (XSComplexTypeDefinition) td;
+ if (ctd.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_ELEMENT) {
+ return true;
+ }
+ if ((td instanceof XSComplexTypeDecl) && ((XSComplexTypeDecl) td).getAbstract()) return true;
+ if (TEXT_ELEMENTS_ARE_COMPLEX) return true;
+ if (ctd.getAttributeUses() != null) {
+ for (int i = 0; i < ctd.getAttributeUses().getLength(); i++) {
+ XSSimpleTypeDefinition xsstd = ((XSAttributeUse) ctd.getAttributeUses().item(i)).getAttrDeclaration().getTypeDefinition();
+ if ("ID".equals(xsstd.getName())) continue;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean checkEnumType(XSTypeDefinition td) {
+ final XSSimpleTypeDefinition st;
+ if (td.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
+ XSComplexTypeDefinition ctd = (XSComplexTypeDefinition) td;
+ if (ctd.getContentType() != XSComplexTypeDefinition.CONTENTTYPE_SIMPLE) return false;
+ if (ctd.getAttributeUses() != null) {
+ for (int i = 0; i < ctd.getAttributeUses().getLength(); i++) {
+ XSSimpleTypeDefinition xsstd = ((XSAttributeUse) ctd.getAttributeUses().item(i)).getAttrDeclaration().getTypeDefinition();
+ if ("ID".equals(xsstd.getName())) continue;
+ return false;
+ }
+ }
+ st = ctd.getSimpleType();
+ } else if (td.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
+ st = (XSSimpleTypeDefinition) td;
+ } else {
+ return false;
+ }
+ return st.getLexicalEnumeration() != null && st.getLexicalEnumeration().getLength() != 0;
+ }
+
+ private static boolean checkBooleanType(XSTypeDefinition td) {
+ if (td.getTypeCategory() != XSTypeDefinition.SIMPLE_TYPE) return false;
+ final XSSimpleTypeDefinition st = ((XSSimpleTypeDefinition) td);
+ final XSObjectList facets = st.getFacets();
+ for (int i = 0; i < facets.getLength(); i++) {
+ final XSFacet facet = (XSFacet) facets.item(i);
+ if (facet.getFacetKind() == XSSimpleTypeDefinition.FACET_LENGTH) {
+ if ("0".equals(facet.getLexicalFacetValue())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ private XSModel loadSchema(File schemaFile, XMLEntityResolver resolver) throws Exception {
+ // get DOM Implementation using DOM Registry
+ System.setProperty(
+ DOMImplementationRegistry.PROPERTY,
+ "org.apache.xerces.dom.DOMXSImplementationSourceImpl");
+ DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
+ XSImplementation impl = (XSImplementation) registry.getDOMImplementation("XS-Loader");
+ XSLoader schemaLoader = impl.createXSLoader(null);
+ DOMConfiguration config = schemaLoader.getConfig();
+
+ // create Error Handler
+ DOMErrorHandler errorHandler = new DOMErrorHandler() {
+ public boolean handleError(DOMError domError) {
+ Util.log("DOMError: " + domError.getMessage());
+ Object relatedException = domError.getRelatedException();
+ if (relatedException != null) {
+ Util.log("DOMError: " + relatedException);
+ if (relatedException instanceof Throwable) {
+ ((Throwable) relatedException).printStackTrace(System.out);
+ }
+ }
+ return false;
+ }
+ };
+ // set error handler
+ config.setParameter("error-handler", errorHandler);
+ // set validation feature
+ config.setParameter("validate", Boolean.TRUE);
+ // parse document
+ config.setParameter("error-handler", errorHandler);
+ config.setParameter("http://apache.org/xml/properties/internal/entity-resolver", resolver);
+
+ XSModel model = schemaLoader.loadURI(schemaFile.getAbsolutePath());
+ if (model == null) return null;
+ XSNamedMap components = model.getComponents(XSConstants.ELEMENT_DECLARATION);
+ for (int i = 0; i < components.getLength(); i++) {
+ XSObject obj = components.item(i);
+ QName qname = new QName(obj.getNamespace(), obj.getName());
+ String file = this.model.qname2FileMap.get(qname);
+ this.model.qname2FileMap.put(qname, (file == null ? "" : file + ";") + schemaFile.getName());
+ }
+ components = model.getComponents(XSConstants.TYPE_DEFINITION);
+ for (int i = 0; i < components.getLength(); i++) {
+ XSObject obj = components.item(i);
+ QName qname = new QName(obj.getNamespace(), obj.getName());
+ String file = this.model.qname2FileMap.get(qname);
+ this.model.qname2FileMap.put(qname, (file == null ? "" : file) + ":" + schemaFile.getName() + ":");
+ }
+ return model;
+ }
+
+ public void processSchemas(Collection<File> schemas, XMLEntityResolver resolver) throws Exception {
+ Map<String, NamespaceDesc> nsdMap = model.nsdMap;
+ Map<String, TypeDesc> jtMap = model.jtMap;
+ final NamespaceDesc nsdDef = nsdMap.get("");
+ final ArrayList<XSModel> models = new ArrayList<XSModel>();
+ final HashMap<String, XSTypeDefinition> types = new HashMap<String, XSTypeDefinition>();
+ for (File schemaFile : schemas) {
+ String fileName = schemaFile.getPath();
+ if (schemaFile.isDirectory() || !fileName.endsWith(".xsd")) {
+ Util.log("skipping " + fileName);
+ continue;
+ }
+ Util.log("loading " + fileName + "..");
+
+ final XSModel model = loadSchema(schemaFile, resolver);
+ if (model == null) continue;
+
+ final StringList namespaceList = model.getNamespaces();
+ for (int i = 0; i < namespaceList.getLength(); i++) {
+ String ns = namespaceList.item(i);
+ if (!nsdMap.containsKey(ns)) {
+ Util.log("Adding default namespace desc for: " + ns);
+ NamespaceDesc nsd = new NamespaceDesc(ns, nsdDef);
+ nsdMap.put(ns, nsd);
+ }
+ }
+ models.add(model);
+ final XSNamedMap typeDefMap = model.getComponents(XSConstants.TYPE_DEFINITION);
+ for (int i = 0; i < typeDefMap.getLength(); i++) {
+ XSTypeDefinition o = (XSTypeDefinition) typeDefMap.item(i);
+ NamespaceDesc nsd = nsdMap.get(o.getNamespace());
+ if (nsd != null && nsd.skip) continue;
+ final String key = o.getName() + "," + o.getNamespace();
+ types.put(key, o);
+ }
+ final XSNamedMap elementDeclMap = model.getComponents(XSConstants.ELEMENT_DECLARATION);
+ for (int i = 0; i < elementDeclMap.getLength(); i++) {
+ XSElementDeclaration o = (XSElementDeclaration) elementDeclMap.item(i);
+ if (o.getTypeDefinition().getAnonymous() && (o.getTypeDefinition() instanceof XSComplexTypeDefinition)) {
+ //types.put(o.getName() + "," + o.getNamespace(), o);
+ XSComplexTypeDefinition ctd = makeTypeFromAnonymous(o);
+ NamespaceDesc nsd = nsdMap.get(o.getNamespace());
+ if (nsd != null && nsd.skip) continue;
+ final String key = ctd.getName() + "," + ctd.getNamespace();
+ types.put(key, ctd);
+ }
+ }
+ }
+ Util.log(types.size() + " elements loaded, processing..");
+ ArrayList<XSTypeDefinition> toProcess = new ArrayList<XSTypeDefinition>(types.values());
+ ArrayList<XSComplexTypeDefinition> toAdd = new ArrayList<XSComplexTypeDefinition>();
+ for (ListIterator<XSTypeDefinition> it = toProcess.listIterator(); it.hasNext();) {
+ XSTypeDefinition td = it.next();
+ Util.log("processing " + td.getName() + "," + td.getNamespace() + "..");
+ if (checkComplexType(td)) {
+ processType((XSComplexTypeDefinition) td, models, jtMap, nsdMap, toAdd);
+ } else if (checkEnumType(td)) {
+ processEnumType(td, jtMap, nsdMap);
+ }
+ if (toAdd.size() != 0) {
+ for (XSComplexTypeDefinition o : toAdd) {
+ final String key = o.getName() + "," + o.getNamespace();
+ if (!types.containsKey(key)) {
+ Util.log(" adding " + o.getName() + "," + o.getNamespace());
+ types.put(key, o);
+ it.add(o);
+ it.previous();
+ } else {
+ Util.logwarn(key + " already exists");
+ }
+ }
+ toAdd.clear();
+ }
+ }
+ }
+
+ private XSComplexTypeDefinition makeTypeFromAnonymous(XSObject o) {
+ final XSComplexTypeDecl ctd = new XSComplexTypeDecl();
+ if (o instanceof XSElementDeclaration && ((XSElementDeclaration) o).getTypeDefinition() instanceof XSComplexTypeDecl) {
+ final XSComplexTypeDecl ctd1 = (XSComplexTypeDecl) ((XSElementDeclaration) o).getTypeDefinition();
+ final XSObjectListImpl annotations = ctd1.getAnnotations() instanceof XSObjectListImpl ? (XSObjectListImpl) ctd1.getAnnotations() : new XSObjectListImpl();
+ ctd.setValues(o.getName(), ctd1.getNamespace(), ctd1.getBaseType(), ctd1.getDerivationMethod(),
+ ctd1.getFinal(), ctd1.getProhibitedSubstitutions(), ctd1.getContentType(),
+ ctd1.getAbstract(), ctd1.getAttrGrp(), (XSSimpleType) ctd1.getSimpleType(),
+ (XSParticleDecl) ctd1.getParticle(), annotations);
+ ctd.setName(o.getName() + Util.ANONYMOUS_ELEM_TYPE_SUFFIX);
+ } else if (o instanceof XSAttributeDeclaration) {
+ final XSSimpleTypeDecl ctd1 = (XSSimpleTypeDecl) ((XSAttributeDeclaration) o).getTypeDefinition();
+ final XSObjectListImpl annotations = ctd1.getAnnotations() instanceof XSObjectListImpl ? (XSObjectListImpl) ctd1.getAnnotations() : new XSObjectListImpl();
+ ctd.setValues(o.getName(), ctd1.getNamespace(), ctd1.getBaseType(), XSConstants.DERIVATION_RESTRICTION,
+ ctd1.getFinal(), (short) 0, XSComplexTypeDefinition.CONTENTTYPE_SIMPLE,
+ false, new XSAttributeGroupDecl(), ctd1,
+ null, annotations);
+ ctd.setName(o.getName() + Util.ANONYMOUS_ATTR_TYPE_SUFFIX);
+ }
+
+ model.qname2FileMap.put(new QName(ctd.getNamespace(), ctd.getName()), model.qname2FileMap.get(new QName(o.getNamespace(), o.getName())));
+ return ctd;
+ }
+
+ public void processEnumType(XSTypeDefinition def, Map<String, TypeDesc> jtMap, Map<String, NamespaceDesc> nsdMap) throws Exception {
+ boolean complexType = def instanceof XSComplexTypeDefinition;
+ if (!nsdMap.containsKey(def.getNamespace())) {
+ Util.log("Namespace desc not found for: " + def);
+ }
+ final String typeName = toJavaTypeName(def, nsdMap);
+ final TypeDesc td = new TypeDesc(def.getName(), def.getNamespace(), typeName, TypeDesc.TypeEnum.ENUM);
+ final XSComplexTypeDefinition ct = complexType ? (XSComplexTypeDefinition) def : null;
+ final XSSimpleTypeDefinition st = (XSSimpleTypeDefinition) (complexType ? ((XSComplexTypeDefinition) def).getSimpleType() : def);
+ for (int i = 0; i < st.getLexicalEnumeration().getLength(); i++) {
+ final String s = st.getLexicalEnumeration().item(i);
+ td.fdMap.put(s, new FieldDesc(Util.computeEnumConstantName(s, td.name), s));
+ }
+
+ final XSObjectList anns = complexType ? ct.getAnnotations() : st.getAnnotations();
+
+ td.documentation = parseAnnotationString("Enumeration " + def.getNamespace() + ":" + def.getName() + " documentation", anns != null && anns.getLength() > 0 ? ((XSAnnotation) anns.item(0)).getAnnotationString() : null);
+ jtMap.put(model.toJavaQualifiedTypeName(def, nsdMap, true), td);
+ }
+
+ public void processType(XSComplexTypeDefinition def, List<XSModel> models, Map<String, TypeDesc> jtMap, Map<String, NamespaceDesc> nsdMap, ArrayList<XSComplexTypeDefinition> toAdd) throws Exception {
+ if (!nsdMap.containsKey(def.getNamespace())) {
+ Util.log("Namespace desc not found for: " + def);
+ }
+ String typeName = toJavaTypeName(def, nsdMap);
+ TypeDesc td = jtMap.get(model.toJavaQualifiedTypeName(def, nsdMap, false));
+ if (td != null) {
+ if (td.fdMap.size() == 0) {
+ // Util.log("Reusing forward decl: "+typeName);
+ } else {
+ Util.logerr("merging: type names collision: " + typeName);
+ }
+ } else {
+ td = new TypeDesc(def.getName(), def.getNamespace(), typeName, TypeDesc.TypeEnum.CLASS);
+ }
+ XSObjectList anns = def.getAnnotations();
+ td.documentation = parseAnnotationString("Type " + def.getNamespace() + ":" + def.getName() + " documentation",
+ anns != null && anns.getLength() > 0 ? ((XSAnnotation) anns.item(0)).getAnnotationString() : null);
+ TypeDesc tdBase = null;
+ if (checkComplexType(def.getBaseType())) {
+ XSComplexTypeDefinition base = (XSComplexTypeDefinition) def.getBaseType();
+ String typeNameBase = toJavaTypeName(base, nsdMap);
+ if ((tdBase = jtMap.get(model.toJavaQualifiedTypeName(base, nsdMap, false))) == null) {
+ // logwarn("forward decl: "+et);
+ tdBase = new TypeDesc(base.getName(), base.getNamespace(), typeNameBase, TypeDesc.TypeEnum.CLASS);
+ jtMap.put(model.toJavaQualifiedTypeName(base, nsdMap, false), tdBase);
+ }
+ }
+ if (def.getSimpleType() != null || def.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_MIXED) {
+ FieldDesc fd = new FieldDesc(FieldDesc.SIMPLE, "value", "String", null, "null", true);
+ fd.realIndex = td.fdMap.size();
+ td.fdMap.put(fd.name, fd);
+ }
+ XSObjectList attrs = def.getAttributeUses();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ XSAttributeUse au = (XSAttributeUse) attrs.item(i);
+ XSAttributeDeclaration ad = au.getAttrDeclaration();
+ XSSimpleTypeDefinition atd = ad.getTypeDefinition();
+ XSAnnotation ann = ad.getAnnotation();
+ String documentation = parseAnnotationString("Attribute " + ad.getNamespace() + ":" + ad.getName() + " documentation", ann != null ? ann.getAnnotationString() : null);
+ // skip "ID" and "FIXED"
+ if ("ID".equals(atd.getName())) continue;
+ // "language", "dewey-versionType", "boolean"
+ if (ad.getConstraintType() == XSConstants.VC_FIXED) continue;
+ FieldDesc fd1 = new FieldDesc(FieldDesc.ATTR, Util.toJavaFieldName(ad.getName()), "String", null, "null", au.getRequired());
+ fd1.tagName = ad.getName();
+ fd1.documentation = documentation;
+ fd1.realIndex = td.fdMap.size();
+ td.duplicates = Util.addToNameMap(td.fdMap, fd1, false) || td.duplicates;
+ if (checkEnumType(ad.getTypeDefinition())) {
+ XSTypeDefinition etRoot = ad.getTypeDefinition();
+ if (etRoot.getAnonymous()) {
+ etRoot = makeTypeFromAnonymous(ad);
+ if (toAdd != null) toAdd.add((XSComplexTypeDefinition) etRoot);
+ }
+ fd1.type = toJavaTypeName(etRoot, nsdMap);
+ fd1.contentQualifiedName = model.toJavaQualifiedTypeName(etRoot, nsdMap, true);
+ // forward decl
+ if (jtMap.get(fd1.contentQualifiedName) == null) {
+ // logwarn("forward decl: "+et);
+ TypeDesc ftd = new TypeDesc(etRoot.getName(), etRoot.getNamespace(), fd1.type, TypeDesc.TypeEnum.ENUM);
+ jtMap.put(fd1.contentQualifiedName, ftd);
+// // anonymous (simple type) enum
+// if (ad.getTypeDefinition().getAnonymous()) {
+// processEnumType(ad.getTypeDefinition(), jtMap, nsdMap);
+// }
+ }
+ } else {
+ fd1.simpleTypesString = getSimpleTypesString(ad.getTypeDefinition());
+ }
+ }
+ LinkedList<PEntry> plist = new LinkedList<PEntry>();
+ if (def.getParticle() != null) {
+ plist.add(new PEntry(def.getParticle(), false));
+ }
+ processParticles(def, plist, nsdMap, jtMap, td, models, toAdd, tdBase);
+ jtMap.put(model.toJavaQualifiedTypeName(def, nsdMap, false), td);
+ if (td.fdMap.size() == 1 && def.getSimpleType() != null) {
+ // calc type hierarchy for simple content
+ FieldDesc fd = td.fdMap.get("value");
+ fd.simpleTypesString = getSimpleTypesString(def);
+ }
+ }
+
+ private static String getSimpleTypesString(XSTypeDefinition et) {
+ StringBuffer typesHierarchy = new StringBuffer();
+ while (et != null && !"anySimpleType".equals(et.getName()) && !"anyType".equals(et.getName()) && et.getNamespace() != null) {
+ typesHierarchy.append(et.getNamespace().substring(et.getNamespace().lastIndexOf("/") + 1)).append(":").append(et.getName()).append(";");
+ if (et instanceof XSSimpleType) {
+ XSSimpleType simpleType = (XSSimpleType) et;
+ if (simpleType.getVariety() == XSSimpleTypeDefinition.VARIETY_LIST
+ || simpleType.getVariety() == XSSimpleTypeDefinition.VARIETY_UNION) {
+ XSObjectList list = simpleType.getMemberTypes();
+ if (list.getLength() > 0) {
+ typesHierarchy.append("{");
+ for (int i = 0; i < list.getLength(); i++) {
+ typesHierarchy.append(getSimpleTypesString((XSTypeDefinition) list.item(i)));
+ }
+ typesHierarchy.append("}");
+ }
+ }
+ }
+ et = et.getBaseType();
+ }
+ return typesHierarchy.toString();
+ }
+
+ private TypeDesc processGroup(XSModelGroup modelGroup, List<XSModel> models, Map<String, TypeDesc> jtMap, Map<String, NamespaceDesc> nsdMap) {
+ XSModelGroupDefinition def = null;
+ for (XSModel xsModel : models) {
+ XSNamedMap map = xsModel.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
+ for (int i = 0; i < map.getLength(); i++) {
+ XSModelGroupDefinition mg = (XSModelGroupDefinition) map.item(i);
+ final XSModelGroup xsModelGroup = mg.getModelGroup();
+ if (xsModelGroup == modelGroup || xsModelGroup.toString().equals(modelGroup.toString())) {
+ def = mg;
+ break;
+ }
+ }
+ }
+ if (def == null) return null;
+ if (!nsdMap.containsKey(def.getNamespace())) {
+ Util.log("Namespace desc not found for: " + def);
+ }
+ String typeName = toJavaTypeName(def, nsdMap);
+ final String typeQName = model.toJavaQualifiedTypeName(def, nsdMap, false);
+ TypeDesc td = jtMap.get(typeQName);
+ if (td != null) {
+ if (td.type == TypeDesc.TypeEnum.GROUP_INTERFACE) {
+ return td;
+ } else {
+ Util.logerr("type-group conflict: " + typeName);
+ return null;
+ }
+ } else {
+ td = new TypeDesc(def.getName(), def.getNamespace(), typeName, TypeDesc.TypeEnum.GROUP_INTERFACE);
+ }
+
+ XSAnnotation ann = def.getAnnotation();
+ td.documentation = parseAnnotationString("Type " + def.getNamespace() + ":" + def.getName() + " documentation",
+ ann == null ? null : ann.getAnnotationString());
+ td.type = TypeDesc.TypeEnum.GROUP_INTERFACE;
+ LinkedList<PEntry> plist = new LinkedList<PEntry>();
+ for (int i = 0; i < def.getModelGroup().getParticles().getLength(); i++) {
+ XSParticle p = (XSParticle) def.getModelGroup().getParticles().item(i);
+ plist.add(new PEntry(p, false));
+ }
+ processParticles(def, plist, nsdMap, jtMap, td, models, null, null);
+ jtMap.put(typeQName, td);
+ return td;
+ }
+
+ private void processParticles(XSObject def, LinkedList<PEntry> plist, Map<String, NamespaceDesc> nsdMap, Map<String, TypeDesc> jtMap, TypeDesc td, List<XSModel> models, ArrayList<XSComplexTypeDefinition> toAdd, TypeDesc baseClass) {
+ final boolean globalMerge = jtMap.containsKey(model.toJavaQualifiedTypeName(def, nsdMap, td.type == TypeDesc.TypeEnum.ENUM));
+ final HashMap<XSParticle, String> globalChoice = new HashMap<XSParticle, String>();
+ final ArrayList<XSObjectList> choiceList = new ArrayList<XSObjectList>();
+ final ArrayList<TypeDesc> supers = new ArrayList<TypeDesc>();
+ if (baseClass != null) {
+ supers.add(baseClass);
+ }
+ while (!plist.isEmpty()) {
+ final PEntry pentry = plist.removeFirst();
+ final XSParticle p = pentry.p;
+ if (p.getTerm() instanceof XSElementDecl) {
+ final XSElementDecl el = (XSElementDecl) p.getTerm();
+ if (el.getConstraintType() == XSConstants.VC_FIXED) continue;
+ XSTypeDefinition etRoot = el.getTypeDefinition();
+ XSTypeDefinition et = etRoot;
+ XSAnnotation ann = el.getAnnotation();
+ String documentation = parseAnnotationString("Element " + el.getNamespace() + ":" + el.getName() + " documentation", ann != null ? ann.getAnnotationString() : null);
+ final FieldDesc fd1 = new FieldDesc(FieldDesc.STR, Util.toJavaFieldName(el.getName()), et.getName(), null, "null", !pentry.many && p.getMinOccurs() > 0);
+ fd1.documentation = documentation;
+ fd1.tagName = el.getName();
+ while (et.getBaseType() != null && !"anySimpleType".equals(et.getBaseType().getName()) && !"anyType".equals(et.getBaseType().getName())) {
+ et = et.getBaseType();
+ }
+ if (checkEnumType(etRoot)) {
+ if (etRoot.getAnonymous()) {
+ etRoot = makeTypeFromAnonymous(el);
+ if (toAdd != null) toAdd.add((XSComplexTypeDefinition) etRoot);
+ }
+ fd1.type = toJavaTypeName(etRoot, nsdMap);
+ fd1.clType = FieldDesc.OBJ;
+ fd1.contentQualifiedName = model.toJavaQualifiedTypeName(etRoot, nsdMap, true);
+ // forward decl
+ if (!jtMap.containsKey(fd1.contentQualifiedName)) {
+ // logwarn("forward decl: "+et);
+ TypeDesc ftd = new TypeDesc(etRoot.getName(), etRoot.getNamespace(), fd1.type, TypeDesc.TypeEnum.ENUM);
+ jtMap.put(fd1.contentQualifiedName, ftd);
+ }
+ } else if (checkComplexType(etRoot)) {
+ if (etRoot.getAnonymous()) {
+ etRoot = makeTypeFromAnonymous(el);
+ if (toAdd != null) toAdd.add((XSComplexTypeDefinition) etRoot);
+ }
+ fd1.type = toJavaTypeName(etRoot, nsdMap);
+ fd1.clType = FieldDesc.OBJ;
+ fd1.contentQualifiedName = model.toJavaQualifiedTypeName(etRoot, nsdMap, false);
+ // forward decl
+ if (jtMap.get(fd1.contentQualifiedName) == null) {
+ //logwarn("forward decl: "+etRoot);
+ jtMap.put(fd1.contentQualifiedName, new TypeDesc(etRoot.getName(), etRoot.getNamespace(), fd1.type, TypeDesc.TypeEnum.CLASS));
+ }
+ } else if (checkBooleanType(etRoot)) {
+ fd1.type = "boolean";
+ fd1.clType = FieldDesc.BOOL;
+ } else {
+ if (etRoot instanceof XSComplexTypeDefinition) {
+ final XSComplexTypeDefinition ct = (XSComplexTypeDefinition) etRoot;
+ // XXX xerces2.7.1 wierd annotation inheritance bug fix
+ //ann = (XSAnnotation) (ct.getAnnotations()!=null && ct.getAnnotations().getLength()>0?ct.getAnnotations().item(0):null);
+ ann = (XSAnnotation) (ct.getAnnotations() != null && ct.getAnnotations().getLength() > 0 ? ct.getAnnotations().item(ct.getAnnotations().getLength() - 1) : null);
+ documentation = parseAnnotationString("Type " + ct.getNamespace() + ":" + ct.getName() + " documentation", ann != null ? ann.getAnnotationString() : null);
+ if (documentation != null) {
+ fd1.documentation = fd1.documentation != null ? fd1.documentation + "\n" + documentation : documentation;
+ }
+ }
+ fd1.simpleTypesString = getSimpleTypesString(etRoot);
+
+ // "fully-qualified-classType", "jndi-nameType", "transaction-typeType"
+ // "java-identifierType", "pathType"
+ fd1.type = et.getName();
+ if (fd1.type == null) {
+ fd1.type = "String";
+ fd1.def = "null";
+ fd1.clType = FieldDesc.STR;
+// fd1.type = "boolean";
+// fd1.def = "false";
+// fd1.clType = FieldDesc.BOOL;
+ } else if (fd1.type.equals("string") || fd1.type.equals("anyURI")) {
+ fd1.type = "String";
+ } else if (fd1.type.equals("boolean")) {
+ fd1.type = "String";
+ } else if (fd1.type.equals("emptyType")) {
+ fd1.type = "boolean";
+ fd1.def = "false";
+ fd1.clType = FieldDesc.BOOL;
+ } else if (fd1.type.equals("decimal")) {
+ fd1.type = "String";
+ fd1.def = "\"0.0\"";
+ } else if (fd1.type.equals("QName")) {
+ fd1.type = "String";
+ } else if (fd1.type.equals("extensibleType")) {
+ fd1.type = "Object";
+ } else {
+ if (et.getBaseType() != null &&
+ ("anySimpleType".equals(et.getBaseType().getName())
+ || "anyType".equals(et.getBaseType().getName()))) {
+ fd1.type = "String";
+ fd1.def = "null";
+ fd1.clType = FieldDesc.STR;
+ } else {
+ fd1.type = "boolean";
+ fd1.def = "false";
+ fd1.clType = FieldDesc.BOOL;
+ }
+ Util.logwarn("using '" + fd1.type + "' for unknown base type: " + et.getName() + " for " + el);
+ }
+ }
+ if ((pentry.many || p.getMaxOccursUnbounded() || p.getMaxOccurs() > 1) && fd1.clType != FieldDesc.BOOL) {
+ fd1.elementType = fd1.type;
+ fd1.elementName = fd1.name;
+ fd1.type = "List<" + fd1.elementType + ">";
+ fd1.name = Util.pluralize(fd1.name);
+ fd1.def = "new ArrayList(0)";
+ fd1.clType = -fd1.clType;
+ fd1.comment = "array of " + fd1.elementType;
+ }
+ fd1.realIndex = td.fdMap.size();
+ boolean merge = globalMerge || globalChoice.containsKey(p) && globalChoice.values().contains(fd1.name);
+ td.duplicates = Util.addToNameMap(td.fdMap, fd1, merge) || td.duplicates;
+ globalChoice.put(p, fd1.name);
+ } else if (p.getTerm() instanceof XSModelGroup) {
+ boolean addToGlobalChoice = false;
+ boolean many = p.getMaxOccursUnbounded() || p.getMaxOccurs() > 1;
+ XSObjectList l = ((XSModelGroup) p.getTerm()).getParticles();
+ if (!many) {
+ if (((XSModelGroup) p.getTerm()).getCompositor() == XSModelGroup.COMPOSITOR_CHOICE) {
+ addToGlobalChoice = true;
+ choiceList.add(l);
+ } else {
+ // generate group interface???
+ XSModelGroup groupDef = (XSModelGroup) p.getTerm();
+ TypeDesc gtd = processGroup(groupDef, models, jtMap, nsdMap);
+ if (gtd != null) supers.add(gtd);
+ }
+ }
+ if (globalChoice.containsKey(p)) {
+ addToGlobalChoice = true;
+ }
+ for (int i = 0; i < l.getLength(); i++) {
+ final PEntry o = new PEntry((XSParticle) l.item(i), many);
+ plist.add(o);
+ if (addToGlobalChoice && !globalChoice.containsKey(o.p)) {
+ globalChoice.put(o.p, null);
+ }
+ }
+ }
+ }
+ int i = 0;
+ for (Iterator<FieldDesc> it = td.fdMap.values().iterator(); it.hasNext(); i++) {
+ FieldDesc fd = it.next();
+ fd.idx = i;
+ }
+ for (XSObjectList l : choiceList) {
+ final ArrayList<XSParticle> clist = new ArrayList<XSParticle>();
+ final LinkedList<XSParticle> elist = new LinkedList<XSParticle>();
+ for (i = 0; i < l.getLength(); i++) {
+ elist.add((XSParticle) l.item(i));
+ }
+ while (!elist.isEmpty()) {
+ final XSParticle p = elist.removeFirst();
+ if (p.getTerm() instanceof XSModelGroup) {
+ XSObjectList l2 = ((XSModelGroup) p.getTerm()).getParticles();
+ for (int i2 = 0; i2 < l2.getLength(); i2++) {
+ elist.addFirst((XSParticle) l2.item(i2));
+ }
+ } else if (p.getTerm() instanceof XSElementDecl) {
+ clist.add(p);
+ }
+ }
+ boolean choiceOpt = true;
+ FieldDesc[] choice = new FieldDesc[clist.size()];
+ for (i = 0; i < choice.length; i++) {
+ XSParticle p = clist.get(i);
+ XSElementDecl el = (XSElementDecl) p.getTerm();
+ String s = Util.toJavaFieldName(el.getName());
+ if (p.getMaxOccursUnbounded() || p.getMaxOccurs() > 1) {
+ s = Util.pluralize(s);
+ }
+ FieldDesc fd = td.fdMap.get(s);
+ if (fd == null) {
+ fd = td.fdMap.get(Util.pluralize(s));
+ if (fd == null) {
+ Util.logerr("uknown choice element: " + s);
+ }
+ }
+
+ if (fd != null) {
+ choice[i] = fd;
+ choice[i].choice = choice;
+ if (fd.required) choiceOpt = false;
+ }
+ }
+ for (i = 0; i < choice.length; i++) {
+ if (choice[i] != null) {
+ choice[i].choiceOpt = choiceOpt;
+ }
+ }
+ }
+ td.supers = supers.toArray(new TypeDesc[supers.size()]);
+ }
+ public static String parseAnnotationString(String title, String str) {
+ if (str == null) return null;
+ int idx = str.indexOf(":documentation");
+ if (idx == -1) idx = str.indexOf("<documentation");
+ if (idx == -1) return null;
+ idx = str.indexOf(">", idx + 1);
+ if (idx == -1) return null;
+ int idx2 = str.indexOf(":documentation", idx + 1);
+ if (idx2 == -1) idx2 = str.indexOf("</documentation", idx + 1);
+ idx2 = str.lastIndexOf("<", idx2 + 1);
+ str = str.substring(idx + 1, idx2).trim();
+
+ idx = str.indexOf("<![CDATA[");
+ if (idx > -1) {
+ idx = str.indexOf("[", idx + 3);
+ idx2 = str.indexOf("]]>", idx + 1);
+ str = str.substring(idx + 1, idx2);
+ }
+ return "<pre>\n<h3>" + title + "</h3>\n" + str + "\n</pre>";
+ }
+
+ public String toJavaTypeName(XSObject xs, Map<String, NamespaceDesc> nsdMap) {
+ String name = xs.getName();
+ if (name == null) {
+ if (xs instanceof TypeInfo) {
+ name = ((TypeInfo) xs).getTypeName();
+ if (name != null && name.startsWith("#")) {
+ name = name.substring(1);
+ }
+ }
+ }
+ return model.toJavaTypeName(name, xs.getNamespace());
+ }
+
+ public static class PEntry {
+ public PEntry(XSParticle p, boolean many) {
+ this.p = p;
+ this.many = many;
+ }
+
+ XSParticle p;
+ boolean many;
+ }
+
+}
diff --git a/plugins/devkit/src/dom/impl/InspectionsPropertiesReferenceProviderContributor.java b/plugins/devkit/src/dom/impl/InspectionsPropertiesReferenceProviderContributor.java
index 662e78840841..de5ab53b5dab 100644
--- a/plugins/devkit/src/dom/impl/InspectionsPropertiesReferenceProviderContributor.java
+++ b/plugins/devkit/src/dom/impl/InspectionsPropertiesReferenceProviderContributor.java
@@ -30,8 +30,8 @@ public class InspectionsPropertiesReferenceProviderContributor extends PsiRefere
@Override
public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
ElementPattern pattern = XmlPatterns.xmlAttributeValue()
- .withParent(XmlPatterns.xmlAttribute().withLocalName(string().oneOf("key", "groupKey"))
- .withParent(XmlPatterns.xmlTag().withName(string().oneOf("localInspection", "globalInspection"))
+ .withParent(XmlPatterns.xmlAttribute().withLocalName("key", "groupKey")
+ .withParent(XmlPatterns.xmlTag().withName("localInspection", "globalInspection")
.withSuperParent(2, XmlPatterns.xmlTag().withName("idea-plugin"))));
registrar.registerReferenceProvider(pattern, new InspectionsKeyPropertiesReferenceProvider(false),
PsiReferenceRegistrar.DEFAULT_PRIORITY);
diff --git a/plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java b/plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java
index cf629df6796f..2c1aec6f72c7 100644
--- a/plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java
+++ b/plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.InspectionEP;
import com.intellij.ide.TypePresentationService;
-import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
@@ -32,7 +31,6 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
-import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
@@ -125,6 +123,12 @@ class RegisterInspectionFix implements IntentionAction {
final BaseListPopupStep<DomFileElement<IdeaPlugin>> popupStep =
new BaseListPopupStep<DomFileElement<IdeaPlugin>>("Choose Plugin Descriptor", elements) {
+
+ @Override
+ public boolean isSpeedSearchEnabled() {
+ return true;
+ }
+
@Override
public Icon getIconFor(DomFileElement<IdeaPlugin> aValue) {
return TypePresentationService.getService().getIcon(aValue);
@@ -134,11 +138,8 @@ class RegisterInspectionFix implements IntentionAction {
@Override
public String getTextFor(DomFileElement<IdeaPlugin> value) {
final String name = value.getFile().getName();
- if (!Comparing.equal(PluginManager.PLUGIN_XML, name)) {
- return name;
- }
final Module module = value.getModule();
- return module != null ? name + " (" + module.getName() + ")" : name;
+ return module != null ? name + " [" + module.getName() + "]" : name;
}
@Override