2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.xml
.actions
.xmlbeans
;
18 import com
.intellij
.psi
.PsiElement
;
19 import com
.intellij
.psi
.PsiReference
;
20 import com
.intellij
.psi
.XmlRecursiveElementVisitor
;
21 import com
.intellij
.psi
.impl
.source
.tree
.LeafPsiElement
;
22 import com
.intellij
.psi
.meta
.PsiMetaData
;
23 import com
.intellij
.psi
.util
.PsiTreeUtil
;
24 import com
.intellij
.psi
.xml
.XmlAttribute
;
25 import com
.intellij
.psi
.xml
.XmlDocument
;
26 import com
.intellij
.psi
.xml
.XmlFile
;
27 import com
.intellij
.psi
.xml
.XmlTag
;
28 import com
.intellij
.xml
.XmlElementDescriptor
;
29 import com
.intellij
.xml
.XmlNSDescriptor
;
30 import com
.intellij
.xml
.impl
.schema
.XmlNSDescriptorImpl
;
31 import org
.apache
.xmlbeans
.*;
32 import org
.apache
.xmlbeans
.impl
.tool
.CommandLine
;
33 import org
.apache
.xmlbeans
.impl
.xsd2inst
.SampleXmlUtil
;
34 import org
.jetbrains
.annotations
.NotNull
;
41 * @author Konstantin Bulenkov
43 public class Xsd2InstanceUtils
{
44 public static String
generate(String
[] args
) {
45 Set flags
= new HashSet();
46 Set opts
= new HashSet();
58 CommandLine cl
= new CommandLine(args
, flags
, opts
);
60 String
[] badOpts
= cl
.getBadOpts();
61 if (badOpts
.length
> 0) {
62 throw new IllegalArgumentException("Unrecognized option: " + badOpts
[0]);
66 boolean dl
= (cl
.getOpt("dl") != null);
67 boolean nopvr
= (cl
.getOpt("nopvr") != null);
68 boolean noupa
= (cl
.getOpt("noupa") != null);
70 File
[] schemaFiles
= cl
.filesEndingWith(".xsd");
71 String rootName
= cl
.getOpt("name");
73 if (rootName
== null) {
74 throw new IllegalArgumentException("Required option \"-name\" must be present");
77 // Process Schema files
78 List sdocs
= new ArrayList();
79 for (int i
= 0; i
< schemaFiles
.length
; i
++)
83 sdocs
.add(XmlObject
.Factory
.parse(schemaFiles
[i
],
84 (new XmlOptions()).setLoadLineNumbers().setLoadMessageDigest()));
88 throw new IllegalArgumentException("Can not load schema file: " + schemaFiles
[i
] + ": ");
92 XmlObject
[] schemas
= (XmlObject
[]) sdocs
.toArray(new XmlObject
[sdocs
.size()]);
94 SchemaTypeSystem sts
= null;
95 if (schemas
.length
> 0)
97 Collection errors
= new ArrayList();
98 XmlOptions compileOptions
= new XmlOptions();
100 compileOptions
.setCompileDownloadUrls();
102 compileOptions
.setCompileNoPvrRule();
104 compileOptions
.setCompileNoUpaRule();
107 sts
= XmlBeans
.compileXsd(schemas
, XmlBeans
.getBuiltinTypeSystem(), compileOptions
);
108 } catch (XmlException e
) {
109 String out
= "Schema compilation errors: ";
110 for (Object error
: errors
) out
+= "\n" + error
;
111 throw new IllegalArgumentException(out
);
117 throw new IllegalArgumentException("No Schemas to process.");
119 SchemaType
[] globalElems
= sts
.documentTypes();
120 SchemaType elem
= null;
121 for (int i
= 0; i
< globalElems
.length
; i
++)
123 if (rootName
.equals(globalElems
[i
].getDocumentElementName().getLocalPart()))
125 elem
= globalElems
[i
];
131 throw new IllegalArgumentException("Could not find a global element with name \"" + rootName
+ "\"");
135 return SampleXmlUtil
.createSampleForType(elem
);
138 public static XmlElementDescriptor
getDescriptor(XmlTag tag
, String elementName
) {
139 final PsiMetaData metaData
= tag
.getMetaData();
141 if (metaData
instanceof XmlNSDescriptorImpl
) {
142 final XmlNSDescriptorImpl nsDescriptor
= (XmlNSDescriptorImpl
) metaData
;
143 return nsDescriptor
.getElementDescriptor(elementName
, nsDescriptor
.getDefaultNamespace());
149 public static List
<String
> addVariantsFromRootTag(XmlTag rootTag
) {
150 PsiMetaData metaData
= rootTag
.getMetaData();
151 if (metaData
instanceof XmlNSDescriptorImpl
) {
152 XmlNSDescriptorImpl nsDescriptor
= (XmlNSDescriptorImpl
) metaData
;
154 List
<String
> elementDescriptors
= new ArrayList
<String
>();
155 XmlElementDescriptor
[] rootElementsDescriptors
= nsDescriptor
.getRootElementsDescriptors(PsiTreeUtil
.getParentOfType(rootTag
, XmlDocument
.class));
156 for(XmlElementDescriptor e
:rootElementsDescriptors
) {
157 elementDescriptors
.add(e
.getName());
160 return elementDescriptors
;
162 return Collections
.emptyList();
165 public static String
processAndSaveAllSchemas(@NotNull XmlFile file
, @NotNull final Map
<String
, String
> scannedToFileName
,
166 final @NotNull SchemaReferenceProcessor schemaReferenceProcessor
) {
167 final String fileName
= file
.getName();
169 String previous
= scannedToFileName
.get(fileName
);
171 if (previous
!= null) return previous
;
173 scannedToFileName
.put(fileName
, fileName
);
175 final StringBuilder result
= new StringBuilder();
177 file
.acceptChildren(new XmlRecursiveElementVisitor() {
178 @Override public void visitElement(PsiElement psiElement
) {
179 super.visitElement(psiElement
);
180 if (psiElement
instanceof LeafPsiElement
) {
181 final String text
= psiElement
.getText();
186 @Override public void visitXmlAttribute(XmlAttribute xmlAttribute
) {
187 boolean replaced
= false;
189 if (xmlAttribute
.isNamespaceDeclaration()) {
191 final String value
= xmlAttribute
.getValue();
192 result
.append(xmlAttribute
.getText()).append(" ");
194 if (!scannedToFileName
.containsKey(value
)) {
195 final XmlNSDescriptor nsDescriptor
= xmlAttribute
.getParent().getNSDescriptor(value
, true);
197 if (nsDescriptor
!= null) {
198 processAndSaveAllSchemas(nsDescriptor
.getDescriptorFile(), scannedToFileName
, schemaReferenceProcessor
);
201 } else if ("schemaLocation".equals(xmlAttribute
.getName())) {
202 final PsiReference
[] references
= xmlAttribute
.getValueElement().getReferences();
204 if (references
.length
> 0) {
205 PsiElement psiElement
= references
[0].resolve();
207 if (psiElement
instanceof XmlFile
) {
208 final String s
= processAndSaveAllSchemas(((XmlFile
) psiElement
), scannedToFileName
, schemaReferenceProcessor
);
210 result
.append(xmlAttribute
.getName()).append("='").append(s
).append('\'');
216 if (!replaced
) result
.append(xmlAttribute
.getText());
220 schemaReferenceProcessor
.processSchema(fileName
, result
.toString());
224 public interface SchemaReferenceProcessor
{
225 void processSchema(String schemaFileName
, String schemaContent
);