mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
@@ -280,7 +280,7 @@ public class ChangeContextUtil {
|
||||
return refMemberClass;
|
||||
}
|
||||
|
||||
private static boolean canRemoveQualifier(PsiReferenceExpression refExpr) {
|
||||
public static boolean canRemoveQualifier(PsiReferenceExpression refExpr) {
|
||||
try{
|
||||
PsiExpression qualifier = refExpr.getQualifierExpression();
|
||||
if (!(qualifier instanceof PsiReferenceExpression)) return false;
|
||||
|
||||
+3
-3
@@ -27,9 +27,9 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -91,7 +91,7 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
|
||||
}
|
||||
});
|
||||
|
||||
((PsiReferenceExpressionImpl)refExpr).bindToElementViaStaticImport(((PsiMember)resolved).getContainingClass(), ((PsiNamedElement)resolved).getName(), ((PsiJavaFile)file).getImportList());
|
||||
RefactoringUtil.bindToElementViaStaticImport(((PsiMember)resolved).getContainingClass(), ((PsiNamedElement)resolved).getName(), ((PsiJavaFile)file).getImportList());
|
||||
|
||||
file.accept(new JavaRecursiveElementVisitor() {
|
||||
@Override public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
@@ -134,4 +134,4 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+215
-27
@@ -15,28 +15,35 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.actions;
|
||||
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.codeInsight.actions.OptimizeImportsProcessor;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class ReplaceImplementsWithStaticImportAction implements IntentionAction {
|
||||
public class ReplaceImplementsWithStaticImportAction extends PsiElementBaseIntentionAction {
|
||||
private static final Logger LOG = Logger.getInstance("#" + ReplaceImplementsWithStaticImportAction.class.getName());
|
||||
@NonNls private static final String FIND_CONSTANT_FIELD_USAGES = "Find constant field usages...";
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
@@ -48,8 +55,14 @@ public class ReplaceImplementsWithStaticImportAction implements IntentionAction
|
||||
return getText();
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
if (!(file instanceof PsiJavaFile)) return false;
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
if (!(element.getContainingFile() instanceof PsiJavaFile)) return false;
|
||||
if (element instanceof PsiIdentifier) {
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiClass) {
|
||||
return isEmptyClass(project, (PsiClass)parent) && DirectClassInheritorsSearch.search((PsiClass)parent).findFirst() != null;
|
||||
}
|
||||
}
|
||||
final PsiReference psiReference = TargetElementUtilBase.findReference(editor);
|
||||
if (psiReference == null) return false;
|
||||
|
||||
@@ -64,11 +77,13 @@ public class ReplaceImplementsWithStaticImportAction implements IntentionAction
|
||||
final PsiElement target = psiReference.resolve();
|
||||
if (target == null || !(target instanceof PsiClass)) return false;
|
||||
|
||||
PsiClass targetClass = (PsiClass)target;
|
||||
return isEmptyClass(project, (PsiClass)target);
|
||||
}
|
||||
|
||||
private static boolean isEmptyClass(Project project, PsiClass targetClass) {
|
||||
if (!targetClass.isInterface()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiReferenceList extendsList = targetClass.getExtendsList();
|
||||
LOG.assertTrue(extendsList != null);
|
||||
if (extendsList.getReferencedTypes().length > 0) {
|
||||
@@ -78,7 +93,8 @@ public class ReplaceImplementsWithStaticImportAction implements IntentionAction
|
||||
if (objectClass == null) return false;
|
||||
methods.removeAll(Arrays.asList(objectClass.getMethods()));
|
||||
if (methods.size() > 0) return false;
|
||||
} else if (targetClass.getMethods().length > 0){
|
||||
}
|
||||
else if (targetClass.getMethods().length > 0) {
|
||||
return false;
|
||||
}
|
||||
return targetClass.getAllFields().length > 0;
|
||||
@@ -87,30 +103,202 @@ public class ReplaceImplementsWithStaticImportAction implements IntentionAction
|
||||
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
|
||||
if (!CodeInsightUtilBase.preparePsiElementForWrite(file)) return;
|
||||
|
||||
final PsiReference psiReference = file.findReferenceAt(editor.getCaretModel().getOffset());
|
||||
LOG.assertTrue(psiReference != null);
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
final PsiReference psiReference = file.findReferenceAt(offset);
|
||||
if (psiReference != null) {
|
||||
final PsiElement element = psiReference.getElement();
|
||||
|
||||
final PsiElement element = psiReference.getElement();
|
||||
final PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
LOG.assertTrue(psiClass != null);
|
||||
|
||||
final PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
LOG.assertTrue(psiClass != null);
|
||||
final PsiElement target = psiReference.resolve();
|
||||
LOG.assertTrue(target instanceof PsiClass);
|
||||
|
||||
final PsiElement target = psiReference.resolve();
|
||||
LOG.assertTrue(target instanceof PsiClass);
|
||||
final PsiClass targetClass = (PsiClass)target;
|
||||
new WriteCommandAction(project, getText()) {
|
||||
protected void run(Result result) throws Throwable {
|
||||
for (PsiField constField : targetClass.getAllFields()) {
|
||||
final String fieldName = constField.getName();
|
||||
final PsiClass containingClass = constField.getContainingClass();
|
||||
for (PsiReference ref : ReferencesSearch.search(constField)) {
|
||||
final PsiElement psiElement = ref.getElement();
|
||||
if (ref instanceof PsiReferenceExpression) {
|
||||
final PsiElement qualifier = ((PsiReferenceExpression)ref).getQualifier();
|
||||
if (qualifier != null) {
|
||||
if (qualifier instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolved = ((PsiReferenceExpression)qualifier).resolve();
|
||||
if (resolved instanceof PsiClass && !InheritanceUtil.isInheritorOrSelf(psiClass, (PsiClass)resolved, true)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
qualifier.putCopyableUserData(ChangeContextUtil.CAN_REMOVE_QUALIFIER_KEY,
|
||||
ChangeContextUtil.canRemoveQualifier((PsiReferenceExpression)ref));
|
||||
}
|
||||
}
|
||||
bindReference(psiElement.getContainingFile(), constField, containingClass, fieldName, ref, project);
|
||||
}
|
||||
}
|
||||
element.delete();
|
||||
JavaCodeStyleManager.getInstance(project).optimizeImports(file);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
else {
|
||||
final PsiElement identifier = file.findElementAt(offset);
|
||||
LOG.assertTrue(identifier instanceof PsiIdentifier);
|
||||
final PsiElement element = identifier.getParent();
|
||||
LOG.assertTrue(element instanceof PsiClass);
|
||||
final PsiClass targetClass = (PsiClass)element;
|
||||
final Map<PsiFile, Map<PsiField, Set<PsiReference>>> refs = new HashMap<PsiFile, Map<PsiField, Set<PsiReference>>>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
public void run() {
|
||||
for (PsiField field : targetClass.getAllFields()) {
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
for (PsiReference reference : ReferencesSearch.search(field)) {
|
||||
if (reference == null) {
|
||||
continue;
|
||||
}
|
||||
final PsiElement refElement = reference.getElement();
|
||||
if (encodeQualifier(containingClass, reference, targetClass)) continue;
|
||||
final PsiFile psiFile = refElement.getContainingFile();
|
||||
if (psiFile instanceof PsiJavaFile) {
|
||||
Map<PsiField, Set<PsiReference>> references = refs.get(psiFile);
|
||||
if (references == null) {
|
||||
references = new HashMap<PsiField, Set<PsiReference>>();
|
||||
refs.put(psiFile, references);
|
||||
}
|
||||
Set<PsiReference> fieldsRefs = references.get(field);
|
||||
if (fieldsRefs == null) {
|
||||
fieldsRefs = new HashSet<PsiReference>();
|
||||
references.put(field, fieldsRefs);
|
||||
}
|
||||
fieldsRefs.add(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, FIND_CONSTANT_FIELD_USAGES, true, project)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiClass targetClass = (PsiClass)target;
|
||||
final Set<PsiJavaCodeReferenceElement> refs2Unimplement = new HashSet<PsiJavaCodeReferenceElement>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
public void run() {
|
||||
for (PsiClass psiClass : DirectClassInheritorsSearch.search(targetClass)) {
|
||||
PsiFile containingFile = psiClass.getContainingFile();
|
||||
if (!refs.containsKey(containingFile)) {
|
||||
refs.put(containingFile, new HashMap<PsiField, Set<PsiReference>>());
|
||||
}
|
||||
if (collectExtendsImplements(targetClass, psiClass.getExtendsList(), refs2Unimplement)) continue;
|
||||
collectExtendsImplements(targetClass, psiClass.getImplementsList(), refs2Unimplement);
|
||||
}
|
||||
}
|
||||
}, "Find references in implement/extends lists...", true, project)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (PsiField constField : targetClass.getAllFields()) {
|
||||
for (PsiReference ref : ReferencesSearch.search(constField, new LocalSearchScope(psiClass))) {
|
||||
((PsiReferenceExpressionImpl)ref).bindToElementViaStaticImport(targetClass, constField.getName(), ((PsiJavaFile)file).getImportList());
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
for (PsiFile psiFile : refs.keySet()) {
|
||||
final Map<PsiField, Set<PsiReference>> map = refs.get(psiFile);
|
||||
for (PsiField psiField : map.keySet()) {
|
||||
final PsiClass containingClass = psiField.getContainingClass();
|
||||
final String fieldName = psiField.getName();
|
||||
for (PsiReference reference : map.get(psiField)) {
|
||||
bindReference(psiFile, psiField, containingClass, fieldName, reference, project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiJavaCodeReferenceElement referenceElement : refs2Unimplement) {
|
||||
referenceElement.delete();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Set<SmartPsiElementPointer<PsiImportStatementBase>> redundant = new HashSet<SmartPsiElementPointer<PsiImportStatementBase>>();
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project);
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable(){
|
||||
public void run() {
|
||||
for (PsiFile psiFile : refs.keySet()) {
|
||||
final Collection<PsiImportStatementBase> red = codeStyleManager.findRedundantImports((PsiJavaFile)psiFile);
|
||||
if (red != null) {
|
||||
for (PsiImportStatementBase statementBase : red) {
|
||||
redundant.add(pointerManager.createSmartPsiElementPointer(statementBase));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "Collect redundant imports...", true, project)) return;
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
for (SmartPsiElementPointer<PsiImportStatementBase> pointer : redundant) {
|
||||
final PsiImportStatementBase statementBase = pointer.getElement();
|
||||
if (statementBase != null) statementBase.delete();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean encodeQualifier(PsiClass containingClass, PsiReference reference, PsiClass targetClass) {
|
||||
if (reference instanceof PsiReferenceExpression) {
|
||||
final PsiElement qualifier = ((PsiReferenceExpression)reference).getQualifier();
|
||||
if (qualifier != null) {
|
||||
if (qualifier instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolved = ((PsiReferenceExpression)qualifier).resolve();
|
||||
if (resolved == containingClass || resolved instanceof PsiClass && InheritanceUtil.isInheritorOrSelf(targetClass, (PsiClass)resolved, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
qualifier.putCopyableUserData(ChangeContextUtil.CAN_REMOVE_QUALIFIER_KEY,
|
||||
ChangeContextUtil.canRemoveQualifier((PsiReferenceExpression)reference));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
element.delete();
|
||||
new OptimizeImportsProcessor(project, file).run();
|
||||
private static void bindReference(PsiFile psiFile,
|
||||
PsiField psiField,
|
||||
PsiClass containingClass,
|
||||
String fieldName,
|
||||
PsiReference reference,
|
||||
Project project) {
|
||||
if (reference instanceof PsiReferenceExpression) {
|
||||
RefactoringUtil.bindToElementViaStaticImport(containingClass, fieldName, ((PsiJavaFile)psiFile).getImportList());
|
||||
final PsiElement qualifier = ((PsiReferenceExpression)reference).getQualifier();
|
||||
if (qualifier != null) {
|
||||
final Boolean canRemoveQualifier = qualifier.getCopyableUserData(ChangeContextUtil.CAN_REMOVE_QUALIFIER_KEY);
|
||||
if (canRemoveQualifier != null && canRemoveQualifier.booleanValue()) {
|
||||
qualifier.delete();
|
||||
} else {
|
||||
final PsiJavaCodeReferenceElement classReferenceElement =
|
||||
JavaPsiFacade.getElementFactory(project).createReferenceExpression(containingClass);
|
||||
qualifier.replace(classReferenceElement);
|
||||
}
|
||||
}
|
||||
} else if (reference.getElement() instanceof PsiDocMethodOrFieldRef){
|
||||
reference.bindToElement(psiField); //todo refs through inheritors
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean collectExtendsImplements(final PsiClass targetClass,
|
||||
final PsiReferenceList referenceList,
|
||||
final Set<PsiJavaCodeReferenceElement> refs) {
|
||||
if (referenceList != null) {
|
||||
for (PsiJavaCodeReferenceElement referenceElement : referenceList.getReferenceElements()) {
|
||||
if (referenceElement.resolve() == targetClass) {
|
||||
refs.add(referenceElement);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-33
@@ -17,7 +17,6 @@ package com.intellij.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
@@ -47,9 +46,9 @@ import com.intellij.psi.scope.processor.MethodResolverProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.tree.ChildRoleBase;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.CharTable;
|
||||
import com.intellij.util.Function;
|
||||
@@ -59,8 +58,6 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements PsiReferenceExpression, SourceJavaCodeReference {
|
||||
@@ -105,7 +102,7 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
doImportStatic = false;
|
||||
}
|
||||
if (doImportStatic) {
|
||||
bindToElementViaStaticImport(qualifierClass, staticName, importList);
|
||||
RefactoringUtil.bindToElementViaStaticImport(qualifierClass, staticName, importList);
|
||||
}
|
||||
else {
|
||||
PsiManagerEx manager = getManager();
|
||||
@@ -118,34 +115,6 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
return this;
|
||||
}
|
||||
|
||||
public void bindToElementViaStaticImport(final PsiClass qualifierClass, final String staticName, final PsiImportList importList)
|
||||
throws IncorrectOperationException {
|
||||
final String qualifiedName = qualifierClass.getQualifiedName();
|
||||
final List<PsiJavaCodeReferenceElement> refs = getImportsFromClass(importList, qualifiedName);
|
||||
if (refs.size() < CodeStyleSettingsManager.getSettings(getProject()).NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND) {
|
||||
importList.add(JavaPsiFacade.getInstance(getProject()).getElementFactory().createImportStaticStatement(qualifierClass, staticName));
|
||||
} else {
|
||||
for (PsiJavaCodeReferenceElement ref : refs) {
|
||||
final PsiImportStaticStatement importStatement = PsiTreeUtil.getParentOfType(ref, PsiImportStaticStatement.class);
|
||||
if (importStatement != null) {
|
||||
importStatement.delete();
|
||||
}
|
||||
}
|
||||
importList.add(JavaPsiFacade.getInstance(getProject()).getElementFactory().createImportStaticStatement(qualifierClass, "*"));
|
||||
}
|
||||
}
|
||||
|
||||
private static List<PsiJavaCodeReferenceElement> getImportsFromClass(@NotNull PsiImportList importList, String className){
|
||||
final List<PsiJavaCodeReferenceElement> array = new ArrayList<PsiJavaCodeReferenceElement>();
|
||||
for (PsiImportStaticStatement staticStatement : importList.getImportStaticStatements()) {
|
||||
final PsiClass psiClass = staticStatement.resolveTargetClass();
|
||||
if (psiClass != null && Comparing.strEqual(psiClass.getQualifiedName(), className)) {
|
||||
array.add(staticStatement.getImportReference());
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public void setQualifierExpression(@Nullable PsiExpression newQualifier) throws IncorrectOperationException {
|
||||
final PsiExpression oldQualifier = getQualifierExpression();
|
||||
if (newQualifier == null) {
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.controlFlow.ControlFlowUtil;
|
||||
@@ -62,6 +63,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.psi.JavaTokenType.*;
|
||||
|
||||
public class RefactoringUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.RefactoringUtil");
|
||||
public static final int EXPR_COPY_SAFE = 0;
|
||||
@@ -882,6 +885,34 @@ public class RefactoringUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindToElementViaStaticImport(final PsiClass qualifierClass, final String staticName, final PsiImportList importList)
|
||||
throws IncorrectOperationException {
|
||||
final String qualifiedName = qualifierClass.getQualifiedName();
|
||||
final List<PsiJavaCodeReferenceElement> refs = getImportsFromClass(importList, qualifiedName);
|
||||
if (refs.size() < CodeStyleSettingsManager.getSettings(qualifierClass.getProject()).NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND) {
|
||||
importList.add(JavaPsiFacade.getInstance(qualifierClass.getProject()).getElementFactory().createImportStaticStatement(qualifierClass, staticName));
|
||||
} else {
|
||||
for (PsiJavaCodeReferenceElement ref : refs) {
|
||||
final PsiImportStaticStatement importStatement = PsiTreeUtil.getParentOfType(ref, PsiImportStaticStatement.class);
|
||||
if (importStatement != null) {
|
||||
importStatement.delete();
|
||||
}
|
||||
}
|
||||
importList.add(JavaPsiFacade.getInstance(qualifierClass.getProject()).getElementFactory().createImportStaticStatement(qualifierClass, "*"));
|
||||
}
|
||||
}
|
||||
|
||||
public static List<PsiJavaCodeReferenceElement> getImportsFromClass(@NotNull PsiImportList importList, String className){
|
||||
final List<PsiJavaCodeReferenceElement> array = new ArrayList<PsiJavaCodeReferenceElement>();
|
||||
for (PsiImportStaticStatement staticStatement : importList.getImportStaticStatements()) {
|
||||
final PsiClass psiClass = staticStatement.resolveTargetClass();
|
||||
if (psiClass != null && Comparing.strEqual(psiClass.getQualifiedName(), className)) {
|
||||
array.add(staticStatement.getImportReference());
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static interface ImplicitConstructorUsageVisitor {
|
||||
void visitConstructor(PsiMethod constructor, PsiMethod baseConstructor);
|
||||
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
|
||||
import static In.FOO;
|
||||
|
||||
interface In {
|
||||
int FOO = 0;
|
||||
}
|
||||
|
||||
class II {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class II1 {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class Uc {
|
||||
static final String FOO = "";
|
||||
void g() {
|
||||
System.out.println("" + In.FOO);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
|
||||
import static In.FOO;
|
||||
|
||||
interface In {
|
||||
int FOO = 0;
|
||||
}
|
||||
|
||||
class II {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link In.FOO}
|
||||
*/
|
||||
class II1 {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class Uc {
|
||||
static final String FOO = "";
|
||||
void g() {
|
||||
System.out.println("" + In.FOO);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
|
||||
import static In.FOO;
|
||||
|
||||
interface In {
|
||||
int FOO = 0;
|
||||
}
|
||||
|
||||
class II {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link I#FOO}
|
||||
*/
|
||||
class II1 {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class Uc {
|
||||
static final String FOO = "";
|
||||
void g() {
|
||||
System.out.println("" + In.FOO);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
|
||||
import static I.BAZZ;
|
||||
import static I.FOO;
|
||||
import static I1.BAZZ;
|
||||
|
||||
public class X {
|
||||
void bar() {
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
|
||||
import static I1.BAZZ;
|
||||
|
||||
public class X implements I {
|
||||
void bar() {
|
||||
System.out.println(FOO);
|
||||
System.out.println(BAZZ);
|
||||
}
|
||||
}
|
||||
|
||||
interface I {
|
||||
String FOO = "foo";
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
String BAZZ = "bazz";
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
|
||||
import static I1.BAZZ;
|
||||
import static II.FOO;
|
||||
|
||||
public class X {
|
||||
void bar() {
|
||||
System.out.println(FOO);
|
||||
System.out.println(BAZZ);
|
||||
}
|
||||
}
|
||||
|
||||
interface II extends I1{
|
||||
String FOO = "foo";
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
String BAZZ = "bazz";
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
|
||||
import static In.FOO;
|
||||
|
||||
interface In {
|
||||
int FOO = 0;
|
||||
}
|
||||
|
||||
class II {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class II1 {
|
||||
int FOO = 9;
|
||||
public static void main(String[] args) {
|
||||
System.out.println(In.FOO);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
interface I<caret>n {
|
||||
int FOO = 0;
|
||||
}
|
||||
|
||||
class II implements In {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class II1 implements In {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(II1.FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class Uc {
|
||||
static final String FOO = "";
|
||||
void g() {
|
||||
System.out.println("" + II.FOO);
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
interface I<caret>n {
|
||||
int FOO = 0;
|
||||
}
|
||||
|
||||
class II implements In {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link In.FOO}
|
||||
*/
|
||||
class II1 implements In {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(II1.FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class Uc {
|
||||
static final String FOO = "";
|
||||
void g() {
|
||||
System.out.println("" + II.FOO);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
|
||||
interface I<caret>n {
|
||||
int FOO = 0;
|
||||
}
|
||||
|
||||
class II implements In {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link I#FOO}
|
||||
*/
|
||||
class II1 implements In {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(II1.FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class Uc {
|
||||
static final String FOO = "";
|
||||
void g() {
|
||||
System.out.println("" + II.FOO);
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
public class X implements I {
|
||||
void bar() {
|
||||
System.out.println(FOO);
|
||||
System.out.println(BAZZ);
|
||||
}
|
||||
}
|
||||
|
||||
interface I extends I1{
|
||||
String FOO = "foo";
|
||||
}
|
||||
|
||||
interface I<caret>1 {
|
||||
String BAZZ = "bazz";
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
public class X implements II {
|
||||
void bar() {
|
||||
System.out.println(FOO);
|
||||
System.out.println(BAZZ);
|
||||
}
|
||||
}
|
||||
|
||||
interface I<caret>I extends I1{
|
||||
String FOO = "foo";
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
String BAZZ = "bazz";
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Replace Implements with Static Import" "true"
|
||||
interface I<caret>n {
|
||||
int FOO = 0;
|
||||
}
|
||||
|
||||
class II implements In {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(FOO);
|
||||
}
|
||||
}
|
||||
|
||||
class II1 implements In {
|
||||
int FOO = 9;
|
||||
public static void main(String[] args) {
|
||||
System.out.println(In.FOO);
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,10 @@ public class ConfigurationContext {
|
||||
final ConfigurationContext context = new ConfigurationContext(dataContext);
|
||||
final DataManager dataManager = DataManager.getInstance();
|
||||
ConfigurationContext sharedContext = dataManager.loadFromDataContext(dataContext, SHARED_CONTEXT);
|
||||
if (sharedContext == null || !Comparing.equal(sharedContext.getLocation().getPsiElement(), context.getLocation().getPsiElement())) {
|
||||
if (sharedContext == null ||
|
||||
sharedContext.getLocation() == null ||
|
||||
context.getLocation() == null ||
|
||||
!Comparing.equal(sharedContext.getLocation().getPsiElement(), context.getLocation().getPsiElement())) {
|
||||
sharedContext = context;
|
||||
dataManager.saveInDataContext(dataContext, SHARED_CONTEXT, sharedContext);
|
||||
}
|
||||
|
||||
+1
-1
@@ -753,7 +753,7 @@ public class DocumentationManager {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DocumentationProvider getProviderFromElement(@Nullable PsiElement element, @Nullable PsiElement originalElement) {
|
||||
public static DocumentationProvider getProviderFromElement(@Nullable PsiElement element, @Nullable PsiElement originalElement) {
|
||||
if (element != null && !element.isValid()) {
|
||||
element = null;
|
||||
}
|
||||
|
||||
+12
-2
@@ -149,13 +149,23 @@ public final class IntentionActionMetaData {
|
||||
return urls.isEmpty() ? null : urls.toArray(new TextDescriptor[urls.size()]);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static URL getIntentionDescriptionDirURL(ClassLoader aClassLoader, String intentionFolderName) {
|
||||
final URL pageURL = aClassLoader.getResource(INTENTION_DESCRIPTION_FOLDER + "/" + intentionFolderName);
|
||||
final URL pageURL = aClassLoader.getResource(INTENTION_DESCRIPTION_FOLDER + "/" + intentionFolderName+"/"+ DESCRIPTION_FILE_NAME);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Path:"+"intentionDescriptions/" + intentionFolderName);
|
||||
LOG.debug("URL:"+pageURL);
|
||||
}
|
||||
return pageURL;
|
||||
if (pageURL != null) {
|
||||
try {
|
||||
final String url = pageURL.toExternalForm();
|
||||
return new URL(url.substring(0, url.lastIndexOf('/')));
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private URL getDirURL() {
|
||||
|
||||
@@ -223,8 +223,8 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String generateInfo(PsiElement element) {
|
||||
final DocumentationProvider documentationProvider = DocumentationManager.getProviderFromElement(element);
|
||||
private static String generateInfo(PsiElement element, PsiElement atPointer) {
|
||||
final DocumentationProvider documentationProvider = DocumentationManager.getProviderFromElement(element, atPointer);
|
||||
|
||||
String info = documentationProvider.getQuickNavigateInfo(element);
|
||||
if (info != null) {
|
||||
@@ -305,7 +305,7 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
@Nullable
|
||||
public String getInfo() {
|
||||
try {
|
||||
return generateInfo(myTargetElement);
|
||||
return generateInfo(myTargetElement, myElementAtPointer);
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
showDumbModeNotification(myTargetElement.getProject());
|
||||
|
||||
+14
-11
@@ -45,7 +45,7 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseRunConfigurationAction extends ActionGroup {
|
||||
private static final Logger LOG = Logger.getInstance("#" + BaseRunConfigurationAction.class.getName());
|
||||
protected static final Logger LOG = Logger.getInstance("#" + BaseRunConfigurationAction.class.getName());
|
||||
|
||||
protected BaseRunConfigurationAction(final String text, final String description, final Icon icon) {
|
||||
super(text, description, icon);
|
||||
@@ -175,12 +175,15 @@ public abstract class BaseRunConfigurationAction extends ActionGroup {
|
||||
public void update(final AnActionEvent event){
|
||||
final ConfigurationContext context = ConfigurationContext.getFromContext(event.getDataContext());
|
||||
final Presentation presentation = event.getPresentation();
|
||||
RunnerAndConfigurationSettings configuration;
|
||||
try {
|
||||
configuration = context.getConfiguration();
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
configuration = null;
|
||||
final RunnerAndConfigurationSettings existing = context.findExisting();
|
||||
RunnerAndConfigurationSettings configuration = existing;
|
||||
if (configuration == null) {
|
||||
try {
|
||||
configuration = context.getConfiguration();
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
configuration = null;
|
||||
}
|
||||
}
|
||||
if (configuration == null){
|
||||
presentation.setEnabled(false);
|
||||
@@ -189,13 +192,13 @@ public abstract class BaseRunConfigurationAction extends ActionGroup {
|
||||
else{
|
||||
presentation.setEnabled(true);
|
||||
presentation.setVisible(true);
|
||||
final String name = suggestRunActionName((LocatableConfiguration)configuration.getConfiguration());
|
||||
final List<RuntimeConfigurationProducer> producers = getEnabledProducers(context);
|
||||
if (!producers.isEmpty()) {
|
||||
//todo[nik,anna] it's dirty fix. Otherwise wrong configuration will be returned from context.getConfiguration()
|
||||
if (existing == null && !producers.isEmpty()) {
|
||||
//todo[nik,anna] it's dirty fix. Otherwise wrong configuration will be returned from context.getConfiguration()
|
||||
context.getConfiguration(producers.get(0));
|
||||
}
|
||||
updatePresentation(presentation, context.findExisting() != null || producers.size() <= 1 ? " " + name : "", context);
|
||||
final String name = suggestRunActionName((LocatableConfiguration)configuration.getConfiguration());
|
||||
updatePresentation(presentation, existing != null || producers.size() <= 1 ? " " + name : "", context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.ide.IconProvider;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -164,6 +165,14 @@ public class PomTargetPsiElementImpl extends RenameableFakePsiElement implements
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Language getLanguage() {
|
||||
if (myTarget instanceof PsiTarget) {
|
||||
return ((PsiTarget)myTarget).getNavigationElement().getLanguage();
|
||||
}
|
||||
return Language.ANY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Project getProject() {
|
||||
|
||||
@@ -26,6 +26,9 @@ import org.jetbrains.annotations.NonNls;
|
||||
* single logical <code>(line; column)</code> pair matches soft wrap-introduced virtual space, i.e. different visual positions
|
||||
* correspond to the same logical position. It's convenient to store exact visual location details within the logical
|
||||
* position in order to relief further {@code 'logical position' -> 'visual position'} mapping.
|
||||
* <p/>
|
||||
* <b>Note:</b> two objects of this class are considered equal if their logical line and column are equal. I.e. all logical positions
|
||||
* for soft wrap-introduced virtual space and the first document symbol after soft wrap are considered to be equal.
|
||||
*
|
||||
* @see Editor#offsetToLogicalPosition(int)
|
||||
* @see Editor#logicalPositionToOffset(LogicalPosition)
|
||||
@@ -134,18 +137,11 @@ public class LogicalPosition implements Comparable<LogicalPosition> {
|
||||
if (!(o instanceof LogicalPosition)) return false;
|
||||
final LogicalPosition logicalPosition = (LogicalPosition) o;
|
||||
|
||||
return column == logicalPosition.column && line == logicalPosition.line && softWrapLines == logicalPosition.softWrapLines
|
||||
&& linesFromActiveSoftWrap == logicalPosition.linesFromActiveSoftWrap
|
||||
&& softWrapColumnDiff == logicalPosition.softWrapColumnDiff && foldedLines == logicalPosition.foldedLines
|
||||
&& foldingColumnDiff == logicalPosition.foldingColumnDiff;
|
||||
return column == logicalPosition.column && line == logicalPosition.line;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = 29 * line + column;
|
||||
result = result * 29 + softWrapLines;
|
||||
result = 29 * result + softWrapColumnDiff;
|
||||
result = 29 * result + foldedLines;
|
||||
return 29 * result + foldingColumnDiff;
|
||||
return 29 * line + column;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 com.intellij.openapi.fileChooser;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class FileTypeDescriptor extends FileChooserDescriptor {
|
||||
private final ArrayList<String> ext;
|
||||
|
||||
public FileTypeDescriptor(String title, @NotNull String... extensions) {
|
||||
super(true, false, false, true, false, false);
|
||||
assert extensions.length > 0 : "There should be at least one extension";
|
||||
ext = new ArrayList<String>(Arrays.asList(extensions));
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
|
||||
final String ex = file.getExtension();
|
||||
return file.isDirectory() || (ex != null && ext.contains(ex.toLowerCase()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileSelectable(VirtualFile file) {
|
||||
return !file.isDirectory() && isFileVisible(file, true);
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -233,10 +233,13 @@ public class EditorActionUtil {
|
||||
}
|
||||
else if (logLineToUse == logCaretLine) {
|
||||
int line = currentVisCaret.line;
|
||||
int column = 0;
|
||||
int column;
|
||||
if (currentVisCaret.column == 0) {
|
||||
column = findSmartIndentColumn(editor, currentVisCaret.line);
|
||||
}
|
||||
else {
|
||||
column = findFirstNonSpaceColumnOnTheLine(editor, currentVisCaret.line);
|
||||
}
|
||||
caretModel.moveToVisualPosition(new VisualPosition(line, column));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -279,7 +279,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
|
||||
|
||||
@NotNull
|
||||
public LogicalPosition adjustLogicalPosition(@NotNull LogicalPosition defaultLogical, @NotNull VisualPosition visual) {
|
||||
if (myActive > 0 || !isSoftWrappingEnabled() || myWraps.isEmpty()) {
|
||||
if (myActive > 0 || !isSoftWrappingEnabled() || myWraps.isEmpty() || myEditor.getDocument().getTextLength() <= 0) {
|
||||
return defaultLogical;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ui.AbstractTableCellEditor;
|
||||
import com.intellij.util.ui.CellEditorComponentWithBrowseButton;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -45,12 +43,7 @@ public class LocalPathCellEditor extends AbstractTableCellEditor {
|
||||
public Component getTableCellEditorComponent(final JTable table, Object value, boolean isSelected, final int row, int column) {
|
||||
ActionListener listener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
FileChooserDescriptor d = new FileChooserDescriptor(false, true, false, true, false, false);
|
||||
if (myTitle != null) {
|
||||
d.setTitle(myTitle);
|
||||
}
|
||||
d.setShowFileSystemRoots(true);
|
||||
|
||||
final FileChooserDescriptor d = getFileChooserDescriptor();
|
||||
VirtualFile initialFile = LocalFileSystem.getInstance().findFileByPath((String)getCellEditorValue());
|
||||
VirtualFile[] files = FileChooser.chooseFiles(table, d, initialFile);
|
||||
if (files.length == 1 && files[0] != null) {
|
||||
@@ -66,4 +59,13 @@ public class LocalPathCellEditor extends AbstractTableCellEditor {
|
||||
myComponent.getChildComponent().setText((String)value);
|
||||
return myComponent;
|
||||
}
|
||||
|
||||
public FileChooserDescriptor getFileChooserDescriptor() {
|
||||
FileChooserDescriptor d = new FileChooserDescriptor(false, true, false, true, false, false);
|
||||
if (myTitle != null) {
|
||||
d.setTitle(myTitle);
|
||||
}
|
||||
d.setShowFileSystemRoots(true);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,21 +111,6 @@ public class IdeaSpecificSettings {
|
||||
replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, JavadocOrderRootType.getInstance(), RELATIVE_MODULE_JAVADOC);
|
||||
modifiableModel.commit();
|
||||
}
|
||||
else {
|
||||
libraryByName = EclipseClasspathReader.findLibraryByName(model.getProject(), libName);
|
||||
if (libraryByName != null) {
|
||||
appendLibraryScope(model, libElement, libraryByName);
|
||||
}
|
||||
final Library[] libraries = model.getModuleLibraryTable().getLibraries();
|
||||
for (Library library : libraries) {
|
||||
final Library.ModifiableModel modifiableModel = library.getModifiableModel();
|
||||
replaceCollapsedByEclipseSourceRoots(libElement, modifiableModel);
|
||||
replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, OrderRootType.SOURCES, RELATIVE_MODULE_SRC);
|
||||
replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, OrderRootType.CLASSES, RELATIVE_MODULE_CLS);
|
||||
replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, JavadocOrderRootType.getInstance(), RELATIVE_MODULE_JAVADOC);
|
||||
modifiableModel.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
<depends optional="true" config-file="groovy-copyright.xml">com.intellij.copyright</depends>
|
||||
<depends optional="true" config-file="intellilang-groovy-support.xml">org.intellij.intelliLang</depends>
|
||||
<depends optional="true">AntSupport</depends>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint name="libraryManager" interface="org.jetbrains.plugins.groovy.config.AbstractGroovyLibraryManager"/>
|
||||
|
||||
+1
-3
@@ -22,7 +22,6 @@ import com.intellij.openapi.util.UserDataHolderEx;
|
||||
import com.intellij.patterns.compiler.PatternCompilerImpl;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.intellij.plugins.intelliLang.inject.InjectorUtils;
|
||||
import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -41,8 +40,7 @@ public class PatternEditorContextMembersProvider extends NonCodeMembersContribut
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
PsiElement place,
|
||||
ResolveState state,
|
||||
ProcessingContext ctx) {
|
||||
ResolveState state) {
|
||||
final PsiFile file = place.getContainingFile().getOriginalFile();
|
||||
final BaseInjection injection = file.getUserData(BaseInjection.INJECTION_KEY);
|
||||
if (injection == null) return;
|
||||
|
||||
+2
-4
@@ -2,7 +2,6 @@ package org.jetbrains.plugins.groovy.annotator.intentions.dynamic;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
@@ -15,10 +14,9 @@ public class DynamicMembersContributor extends NonCodeMembersContributor {
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
PsiElement place,
|
||||
ResolveState state,
|
||||
ProcessingContext ctx) {
|
||||
ResolveState state) {
|
||||
final DynamicManager manager = DynamicManager.getInstance(place.getProject());
|
||||
for (String qName : ResolveUtil.getAllSuperTypes(qualifierType, place, ctx).keySet()) {
|
||||
for (String qName : ResolveUtil.getAllSuperTypes(qualifierType, place).keySet()) {
|
||||
for (PsiMethod method : manager.getMethods(qName)) {
|
||||
if (!ResolveUtil.processElement(processor, method)) return;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrBuilderMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
|
||||
@@ -17,7 +19,7 @@ import java.util.Collections;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class AntBuilderMethod extends LightMethodBuilder {
|
||||
class AntBuilderMethod extends LightMethodBuilder implements GrBuilderMethod {
|
||||
private final PsiFile myPlace;
|
||||
@Nullable private final Class myAntClass;
|
||||
|
||||
@@ -26,7 +28,7 @@ class AntBuilderMethod extends LightMethodBuilder {
|
||||
myPlace = place;
|
||||
myAntClass = antClass;
|
||||
setModifiers(PsiModifier.PUBLIC);
|
||||
addParameter("args", CommonClassNames.JAVA_UTIL_MAP);
|
||||
addParameter("args", new GrMapType(place.getResolveScope()));
|
||||
setBaseIcon(GantIcons.ANT_TASK);
|
||||
addParameter(new GrLightParameter("body", closureType, this).setOptional(true));
|
||||
}
|
||||
@@ -47,10 +49,11 @@ class AntBuilderMethod extends LightMethodBuilder {
|
||||
final AntIntrospector introspector = AntDomExtender.getIntrospector(myAntClass);
|
||||
if (introspector != null) {
|
||||
final NameHint hint = processor.getHint(NameHint.KEY);
|
||||
final PsiType closureType = getParameterList().getParameters()[1].getType();
|
||||
|
||||
for (String name : Collections.list(introspector.getNestedElements())) {
|
||||
if (hint == null || hint.getName(ResolveState.initial()).equals(name)) {
|
||||
final AntBuilderMethod method = new AntBuilderMethod(myPlace, name, getParameterList().getParameters()[1].getType(), null);
|
||||
final AntBuilderMethod method = new AntBuilderMethod(myPlace, name, closureType, introspector.getElementType(name));
|
||||
if (!ResolveUtil.processElement(processor, method)) {
|
||||
return false;
|
||||
}
|
||||
@@ -59,4 +62,9 @@ class AntBuilderMethod extends LightMethodBuilder {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasObligatoryNamedArguments() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.psi.impl.light.LightMethodBuilder;
|
||||
import com.intellij.psi.impl.light.LightVariableBuilder;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
|
||||
@@ -38,9 +37,8 @@ public class GantMemberContributor extends NonCodeMembersContributor {
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
PsiElement place,
|
||||
ResolveState state,
|
||||
ProcessingContext ctx) {
|
||||
if (ResolveUtil.isInheritor(qualifierType, "groovy.util.AntBuilder", place, ctx)) {
|
||||
ResolveState state) {
|
||||
if (ResolveUtil.isInheritor(qualifierType, "groovy.util.AntBuilder", place)) {
|
||||
processAntTasks(processor, place);
|
||||
return;
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public interface GrBuilderMethod {
|
||||
|
||||
boolean hasObligatoryNamedArguments();
|
||||
|
||||
}
|
||||
+2
-4
@@ -2,7 +2,6 @@ package org.jetbrains.plugins.groovy.lang.psi.impl;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
@@ -15,10 +14,9 @@ public class GdkMembersContributor extends NonCodeMembersContributor {
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
PsiElement place,
|
||||
ResolveState state,
|
||||
ProcessingContext ctx) {
|
||||
ResolveState state) {
|
||||
final GroovyPsiManager manager = GroovyPsiManager.getInstance(place.getProject());
|
||||
for (String qName : ResolveUtil.getAllSuperTypes(qualifierType, place, ctx).keySet()) {
|
||||
for (String qName : ResolveUtil.getAllSuperTypes(qualifierType, place).keySet()) {
|
||||
for (PsiMethod defaultMethod : manager.getDefaultMethods(qName)) {
|
||||
if (!ResolveUtil.processElement(processor, defaultMethod)) return;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ public class GrMapType extends GrLiteralClassType {
|
||||
private final String myJavaClassName;
|
||||
|
||||
|
||||
public GrMapType(GlobalSearchScope scope) {
|
||||
this(JavaPsiFacade.getInstance(scope.getProject()), scope, Collections.<String, PsiType>emptyMap(), Collections.<Pair<PsiType, PsiType>>emptyList(), LanguageLevel.JDK_1_5);
|
||||
}
|
||||
|
||||
public GrMapType(JavaPsiFacade facade,
|
||||
GlobalSearchScope scope,
|
||||
Map<String, PsiType> stringEntries,
|
||||
@@ -144,7 +148,7 @@ public class GrMapType extends GrLiteralClassType {
|
||||
}
|
||||
|
||||
public boolean isAssignableFrom(@NotNull PsiType type) {
|
||||
return false;
|
||||
return type instanceof GrMapType || myFacade.getElementFactory().createTypeFromText(getJavaClassName(), null).isAssignableFrom(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ public class GrConstructorInvocationImpl extends GroovyPsiElementImpl implements
|
||||
for (NonCodeMembersProcessor membersProcessor : NonCodeMembersProcessor.EP_NAME.getExtensions()) {
|
||||
if (!membersProcessor.processNonCodeMembers(thisType, processor, this, true)) break;
|
||||
}
|
||||
NonCodeMembersContributor.processDynamicElements(thisType, processor, this, ResolveState.initial());
|
||||
NonCodeMembersContributor.runContributors(thisType, processor, this, ResolveState.initial());
|
||||
|
||||
return processor.getCandidates();
|
||||
}
|
||||
|
||||
+1
-1
@@ -138,7 +138,7 @@ public class GrArgumentLabelImpl extends GroovyPsiElementImpl implements GrArgum
|
||||
if (field != null) return field;
|
||||
final PropertyResolverProcessor processor = new PropertyResolverProcessor(propName, this);
|
||||
ResolveUtil
|
||||
.processNonCodeMethods(JavaPsiFacade.getElementFactory(getProject()).createType(clazz), processor, getProject(), this, false);
|
||||
.processNonCodeMethods(JavaPsiFacade.getElementFactory(getProject()).createType(clazz), processor, this, false);
|
||||
final GroovyResolveResult[] candidates = processor.getCandidates();
|
||||
if (candidates.length == 0) return null;
|
||||
return candidates[0].getElement();
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock
|
||||
|
||||
// Process non-code in closures
|
||||
PsiType clType = JavaPsiFacade.getInstance(getProject()).getElementFactory().createType(closureClass, PsiSubstitutor.EMPTY);
|
||||
if (!ResolveUtil.processNonCodeMethods(clType, processor, getProject(), place, true)) return false;
|
||||
if (!ResolveUtil.processNonCodeMethods(clType, processor, place, true)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+2
-2
@@ -284,7 +284,7 @@ public class CompleteReferenceExpression {
|
||||
javaLangClass.processDeclarations(processor, ResolveState.initial(), null, refExpr);
|
||||
PsiType javaLangClassType =
|
||||
JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory().createType(javaLangClass, substitutor);
|
||||
ResolveUtil.processNonCodeMethods(javaLangClassType, processor, refExpr.getProject(), refExpr, true);
|
||||
ResolveUtil.processNonCodeMethods(javaLangClassType, processor, refExpr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,6 +352,6 @@ public class CompleteReferenceExpression {
|
||||
return;
|
||||
}
|
||||
|
||||
ResolveUtil.processNonCodeMethods(qualifierType, processor, project, refExpr, true);
|
||||
ResolveUtil.processNonCodeMethods(qualifierType, processor, refExpr, true);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -624,7 +624,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
|
||||
}
|
||||
if (!javaLangClass.processDeclarations(processor, state, null, refExpr)) return;
|
||||
PsiType javaLangClassType = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory().createType(javaLangClass, substitutor);
|
||||
ResolveUtil.processNonCodeMethods(javaLangClassType, processor, refExpr.getProject(), refExpr, false);
|
||||
ResolveUtil.processNonCodeMethods(javaLangClassType, processor, refExpr, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -653,7 +653,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
|
||||
return;
|
||||
}
|
||||
|
||||
ResolveUtil.processNonCodeMethods(qualifierType, processor, project, refExpr, false);
|
||||
ResolveUtil.processNonCodeMethods(qualifierType, processor, refExpr, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ public class TypesUtil {
|
||||
}
|
||||
}
|
||||
|
||||
ResolveUtil.processNonCodeMethods(thisType, processor, place.getProject(), place, false);
|
||||
ResolveUtil.processNonCodeMethods(thisType, processor, place, false);
|
||||
return processor.getCandidates();
|
||||
}
|
||||
return GroovyResolveResult.EMPTY_ARRAY;
|
||||
|
||||
@@ -58,14 +58,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrPropertySelection;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.JavaIdentifier;
|
||||
@@ -136,7 +134,19 @@ public class PsiUtil {
|
||||
return InheritanceUtil.isInheritor(argumentTypes[0], CommonClassNames.JAVA_UTIL_MAP);
|
||||
}
|
||||
LOG.assertTrue(signature != null);
|
||||
return GrClosureSignatureUtil.isSignatureApplicable(signature, argumentTypes, place);
|
||||
if (GrClosureSignatureUtil.isSignatureApplicable(signature, argumentTypes, place)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (method instanceof GrBuilderMethod &&
|
||||
!((GrBuilderMethod)method).hasObligatoryNamedArguments()) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length > 0 && parameters[0].getType() instanceof GrMapType &&
|
||||
(argumentTypes.length == 0 || !(argumentTypes[0] instanceof GrMapType))) {
|
||||
return GrClosureSignatureUtil.isSignatureApplicable(signature.curry(1), argumentTypes, place);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isApplicable(@Nullable PsiType[] argumentTypes, GrClosureType type, GroovyPsiElement context) {
|
||||
@@ -147,7 +157,7 @@ public class PsiUtil {
|
||||
}
|
||||
|
||||
public static PsiClassType createMapType(PsiManager manager, GlobalSearchScope scope) {
|
||||
return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_UTIL_MAP, scope);
|
||||
return new GrMapType(scope);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -631,7 +641,7 @@ public class PsiUtil {
|
||||
qClass.processDeclarations(processor, ResolveState.initial().put(PsiSubstitutor.KEY, PsiSubstitutor.EMPTY), null, expr);
|
||||
}
|
||||
|
||||
ResolveUtil.processNonCodeMethods(qualifierType, processor, expr.getProject(), expr, false);
|
||||
ResolveUtil.processNonCodeMethods(qualifierType, processor, expr, false);
|
||||
final GroovyResolveResult[] candidates = processor.getCandidates();
|
||||
PsiType type = null;
|
||||
if (candidates.length == 1) {
|
||||
@@ -828,7 +838,7 @@ public class PsiUtil {
|
||||
for (NonCodeMembersProcessor membersProcessor : NonCodeMembersProcessor.EP_NAME.getExtensions()) {
|
||||
if (!membersProcessor.processNonCodeMembers(thisType, processor, place, true)) break;
|
||||
}
|
||||
NonCodeMembersContributor.processDynamicElements(thisType, processor, place, ResolveState.initial());
|
||||
NonCodeMembersContributor.runContributors(thisType, processor, place, ResolveState.initial());
|
||||
constructorResults.addAll(Arrays.asList(processor.getCandidates()));
|
||||
if (!toBreak) break;
|
||||
}
|
||||
|
||||
+6
-5
@@ -23,7 +23,6 @@ import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.DelegatingScopeProcessor;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -32,13 +31,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
public abstract class NonCodeMembersContributor {
|
||||
private static final ExtensionPointName<NonCodeMembersContributor> EP_NAME = ExtensionPointName.create("org.intellij.groovy.membersContributor");
|
||||
|
||||
public abstract void processDynamicElements(@NotNull PsiType qualifierType, PsiScopeProcessor processor, PsiElement place, ResolveState state, ProcessingContext ctx);
|
||||
public abstract void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
PsiElement place,
|
||||
ResolveState state);
|
||||
|
||||
public static boolean processDynamicElements(@NotNull final PsiType qualifierType,
|
||||
public static boolean runContributors(@NotNull final PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
final PsiElement place,
|
||||
final ResolveState state) {
|
||||
final ProcessingContext ctx = new ProcessingContext();
|
||||
final Ref<Boolean> result = Ref.create(true);
|
||||
final PsiScopeProcessor wrapper = new DelegatingScopeProcessor(processor) {
|
||||
@Override
|
||||
@@ -52,7 +53,7 @@ public abstract class NonCodeMembersContributor {
|
||||
}
|
||||
};
|
||||
for (final NonCodeMembersContributor contributor : EP_NAME.getExtensions()) {
|
||||
contributor.processDynamicElements(qualifierType, wrapper, place, state, ctx);
|
||||
contributor.processDynamicElements(qualifierType, wrapper, place, state);
|
||||
if (!result.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.plugins.groovy.lang.resolve;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
@@ -24,11 +25,11 @@ import com.intellij.psi.scope.JavaScopeProcessorEvent;
|
||||
import com.intellij.psi.scope.NameHint;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||
import com.intellij.util.containers.ConcurrentHashMap;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex;
|
||||
@@ -60,7 +61,19 @@ import java.util.*;
|
||||
*/
|
||||
@SuppressWarnings({"StringBufferReplaceableByString"})
|
||||
public class ResolveUtil {
|
||||
public static final PsiScopeProcessor.Event DECLARATION_SCOPE_PASSED = new PsiScopeProcessor.Event() {
|
||||
public static final PsiScopeProcessor.Event DECLARATION_SCOPE_PASSED = new PsiScopeProcessor.Event() {};
|
||||
private static final Key<CachedValue<FactoryMap<PsiType, Map<String, PsiType>>>> SUPER_TYPES = Key.create("SUPER_TYPES");
|
||||
|
||||
private static final TObjectHashingStrategy<PsiType> RAW_TYPE_HASHING_STRATEGY = new TObjectHashingStrategy<PsiType>() {
|
||||
@Override
|
||||
public int computeHashCode(PsiType object) {
|
||||
return rawCanonicalText(object).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(PsiType o1, PsiType o2) {
|
||||
return rawCanonicalText(o1).equals(rawCanonicalText(o2));
|
||||
}
|
||||
};
|
||||
|
||||
private ResolveUtil() {
|
||||
@@ -77,12 +90,12 @@ public class ResolveUtil {
|
||||
if (!run.processDeclarations(processor, ResolveState.initial(), lastParent, place)) return false;
|
||||
if (processNonCodeMethods) {
|
||||
if (run instanceof GrTypeDefinition) {
|
||||
processNonCodeMethods(factory.createType(((GrTypeDefinition)run)), processor, project, place, false);
|
||||
processNonCodeMethods(factory.createType(((GrTypeDefinition)run)), processor, place, false);
|
||||
}
|
||||
else if ((run instanceof GroovyFileBase) && ((GroovyFileBase)run).isScript()) {
|
||||
final PsiClass psiClass = ((GroovyFileBase)run).getScriptClass();
|
||||
if (psiClass != null) {
|
||||
processNonCodeMethods(factory.createType(psiClass), processor, project, place, false);
|
||||
processNonCodeMethods(factory.createType(psiClass), processor, place, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,16 +134,9 @@ public class ResolveUtil {
|
||||
|
||||
public static boolean processNonCodeMethods(PsiType type,
|
||||
PsiScopeProcessor processor,
|
||||
Project project,
|
||||
PsiElement place,
|
||||
boolean forCompletion) {
|
||||
String qName = rawCanonicalText(type);
|
||||
|
||||
if (qName == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!NonCodeMembersContributor.processDynamicElements(type, processor, place, ResolveState.initial())) {
|
||||
if (!NonCodeMembersContributor.runContributors(type, processor, place, ResolveState.initial())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -141,8 +147,7 @@ public class ResolveUtil {
|
||||
}
|
||||
}
|
||||
|
||||
final HashMap<String, PsiType> visited = getSuperTypes(type, project);
|
||||
for (PsiType psiType : visited.values()) {
|
||||
for (PsiType psiType : getAllSuperTypes(type, place).values()) {
|
||||
for (NonCodeMembersProcessor membersProcessor : NonCodeMembersProcessor.EP_NAME.getExtensions()) {
|
||||
if (!membersProcessor.processNonCodeMembers(psiType, processor, place, forCompletion)) return false;
|
||||
}
|
||||
@@ -152,51 +157,59 @@ public class ResolveUtil {
|
||||
|
||||
private static HashMap<String, PsiType> getSuperTypes(PsiType type, Project project) {
|
||||
final HashMap<String, PsiType> visited = new HashMap<String, PsiType>();
|
||||
collectSuperTypes(type, visited, project);
|
||||
collectSuperTypes(type, visited);
|
||||
if (type instanceof PsiArrayType) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
collectSuperTypes(factory.createTypeFromText(CommonClassNames.JAVA_LANG_COMPARABLE, null), visited, project);
|
||||
collectSuperTypes(factory.createTypeFromText(CommonClassNames.JAVA_IO_SERIALIZABLE, null), visited, project);
|
||||
collectSuperTypes(factory.createTypeFromText(CommonClassNames.JAVA_LANG_COMPARABLE, null), visited);
|
||||
collectSuperTypes(factory.createTypeFromText(CommonClassNames.JAVA_IO_SERIALIZABLE, null), visited);
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
|
||||
private static void collectSuperTypes(PsiType type, Map<String, PsiType> visited, Project project) {
|
||||
private static void collectSuperTypes(PsiType type, Map<String, PsiType> visited) {
|
||||
String qName = rawCanonicalText(type);
|
||||
|
||||
if (qName == null || visited.put(qName, type) != null) {
|
||||
if (visited.put(qName, type) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (PsiType superType : type.getSuperTypes()) {
|
||||
collectSuperTypes(TypeConversionUtil.erasure(superType), visited, project);
|
||||
collectSuperTypes(TypeConversionUtil.erasure(superType), visited);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Key<FactoryMap<PsiType, Map<String, PsiType>>> SUPER_TYPES = Key.create("SUPER_TYPES");
|
||||
public static Map<String, PsiType> getAllSuperTypes(PsiType base, final PsiElement place, ProcessingContext ctx) {
|
||||
FactoryMap<PsiType, Map<String, PsiType>> classes = ctx.get(SUPER_TYPES);
|
||||
if (classes == null) {
|
||||
ctx.put(SUPER_TYPES, classes = new FactoryMap<PsiType, Map<String, PsiType>>() {
|
||||
@Override
|
||||
protected Map<String, PsiType> create(PsiType key) {
|
||||
return getSuperTypes(key, place.getProject());
|
||||
}
|
||||
});
|
||||
}
|
||||
return classes.get(base);
|
||||
public static Map<String, PsiType> getAllSuperTypes(PsiType base, final PsiElement place) {
|
||||
final Project project = place.getProject();
|
||||
return CachedValuesManager.getManager(project).getCachedValue(project, SUPER_TYPES, new CachedValueProvider<FactoryMap<PsiType, Map<String, PsiType>>>() {
|
||||
@Override
|
||||
public Result<FactoryMap<PsiType, Map<String, PsiType>>> compute() {
|
||||
final FactoryMap<PsiType, Map<String, PsiType>> map = new ConcurrentFactoryMap<PsiType, Map<String, PsiType>>() {
|
||||
|
||||
@Override
|
||||
protected Map<PsiType, Map<String, PsiType>> createMap() {
|
||||
return new ConcurrentHashMap<PsiType, Map<String, PsiType>>(RAW_TYPE_HASHING_STRATEGY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, PsiType> create(PsiType key) {
|
||||
return getSuperTypes(key, project);
|
||||
}
|
||||
};
|
||||
return Result.create(map, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, ProjectRootManager.getInstance(project));
|
||||
}
|
||||
}, false).get(base);
|
||||
}
|
||||
|
||||
public static boolean isInheritor(PsiType type, @NotNull String baseClass, PsiElement place, ProcessingContext ctx) {
|
||||
return getAllSuperTypes(type, place, ctx).keySet().contains(baseClass);
|
||||
public static boolean isInheritor(PsiType type, @NotNull String baseClass, PsiElement place) {
|
||||
return getAllSuperTypes(type, place).keySet().contains(baseClass);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static String rawCanonicalText(PsiType type) {
|
||||
@NotNull
|
||||
private static String rawCanonicalText(@NotNull PsiType type) {
|
||||
final String result = type.getCanonicalText();
|
||||
if (result == null) return null;
|
||||
if (result == null) return "";
|
||||
final int i = result.indexOf('<');
|
||||
if (i > 0) return result.substring(0, i);
|
||||
return result;
|
||||
@@ -446,7 +459,7 @@ public class ResolveUtil {
|
||||
}
|
||||
}
|
||||
else if (parent instanceof GrApplicationStatement) {
|
||||
final GrExpression funExpr = ((GrApplicationStatement) parent).getFunExpression();
|
||||
final GrExpression funExpr = ((GrApplicationStatement) parent).getInvokedExpression();
|
||||
if (funExpr instanceof GrReferenceExpression) {
|
||||
variants = ((GrReferenceExpression) funExpr).getSameNameVariants();
|
||||
}
|
||||
@@ -459,7 +472,7 @@ public class ResolveUtil {
|
||||
public static GroovyResolveResult[] getConstructorResolveResult(PsiMethod[] constructors, PsiElement place) {
|
||||
GroovyResolveResult[] variants = new GroovyResolveResult[constructors.length];
|
||||
for (int i = 0; i < constructors.length; i++) {
|
||||
final boolean isAccessible = com.intellij.psi.util.PsiUtil.isAccessible(constructors[i], place, null);
|
||||
final boolean isAccessible = PsiUtil.isAccessible(constructors[i], place, null);
|
||||
variants[i] = new GroovyResolveResultImpl(constructors[i], isAccessible);
|
||||
}
|
||||
return variants;
|
||||
|
||||
+1
-3
@@ -19,7 +19,6 @@ package org.jetbrains.plugins.groovy.lang.resolve.noncode;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.annotator.inspections.GroovyImmutableAnnotationInspection;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
@@ -34,8 +33,7 @@ public class ImmutableAnnotationProcessor extends NonCodeMembersContributor {
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
PsiElement place,
|
||||
ResolveState state,
|
||||
ProcessingContext ctx) {
|
||||
ResolveState state) {
|
||||
if (!(qualifierType instanceof PsiClassType)) return;
|
||||
|
||||
PsiClass psiClass = ((PsiClassType)qualifierType).resolve();
|
||||
|
||||
+5
-1
@@ -64,7 +64,11 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC
|
||||
getProject().getComponent(GroovyCompilerLoader.class).projectOpened();
|
||||
CompilerManagerImpl.testSetup();
|
||||
|
||||
CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl());
|
||||
new WriteCommandAction(getProject()) {
|
||||
protected void run(Result result) throws Throwable {
|
||||
CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl());
|
||||
}
|
||||
}.execute();
|
||||
|
||||
addGroovyLibrary(myModule, getName().contains("1_7"));
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.jetbrains.plugins.groovy.gant.completion;
|
||||
package org.jetbrains.plugins.groovy.gant;
|
||||
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
+25
-2
@@ -1,4 +1,4 @@
|
||||
package org.jetbrains.plugins.groovy.gant.completion;
|
||||
package org.jetbrains.plugins.groovy.gant;
|
||||
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
@@ -10,7 +10,7 @@ import org.jetbrains.plugins.groovy.util.TestUtils
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class StandaloneGantCompletionTest extends LightCodeInsightFixtureTestCase {
|
||||
public class StandaloneGantTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
@@ -47,6 +47,29 @@ target(aaa: "") {
|
||||
checkVariants "ant.patt<caret>t", "patternset"
|
||||
}
|
||||
|
||||
public void testOptionalArgumentsHighlighting() throws Exception {
|
||||
myFixture.configureByText "a.gant", """
|
||||
ant.java(classname: "com.intellij.util.io.zip.ReorderJarsMain", fork: "true") {
|
||||
arg(value: "aaa")
|
||||
classpath {
|
||||
pathelement(location: "sss")
|
||||
}
|
||||
}
|
||||
"""
|
||||
myFixture.checkHighlighting(true, false, false)
|
||||
}
|
||||
|
||||
public void testPathElement() throws Exception {
|
||||
checkVariants """
|
||||
ant.java(classname: "com.intellij.util.io.zip.ReorderJarsMain", fork: "true") {
|
||||
arg(value: "aaa")
|
||||
classpath {
|
||||
pathele<caret>ment(location: "sss")
|
||||
}
|
||||
}
|
||||
""", "pathelement"
|
||||
}
|
||||
|
||||
static final def GANT_JARS = ["gant.jar", "ant.jar", "ant-junit.jar", "ant-launcher.jar", "commons.jar"]
|
||||
|
||||
}
|
||||
@@ -269,6 +269,7 @@
|
||||
|
||||
<action id="ScanSourceCommentsAction" internal="true" class="com.intellij.tools.ScanSourceCommentsAction" text="Dump all comments in the project"/>
|
||||
<action internal="true" id="CompilerTest" class="com.intellij.compiler.impl.javaCompiler.api.CompilerPerfTestAction" text="Test Rebuild Performance"/>
|
||||
<action internal="true" id="GenerateDomModel" class="com.intellij.util.dom.generator.GenerateDomModelAction" text="Generate Dom Model"/>
|
||||
|
||||
<add-to-group group-id="Internal" anchor="last"/>
|
||||
</group>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<orderEntry type="module" module-name="lang-api" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="xml-openapi" />
|
||||
<orderEntry type="library" name="DTDParser" level="project" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class DGNamespace {
|
||||
public final String name;
|
||||
public boolean skip = false;
|
||||
public String superClass = null;
|
||||
public String enums = null;
|
||||
|
||||
|
||||
public DGNamespace(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import com.wutka.dtd.*;
|
||||
import org.apache.xerces.xni.parser.XMLEntityResolver;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 com.intellij.util.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();
|
||||
init();
|
||||
getOKAction().putValue(Action.NAME, "Generate");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return comp;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
final String location = panel.getLocation();
|
||||
ModelLoader loader = location.toLowerCase().endsWith(".xsd") ? new XSDModelLoader() : new DTDModelLoader();
|
||||
final ModelGen modelGen = new ModelGen(loader);
|
||||
final NamespaceDesc desc = panel.getNamespaceDescriptor();
|
||||
modelGen.setConfig(desc.name, location, desc);
|
||||
try {
|
||||
final File output = new File(panel.getOutputDir());
|
||||
modelGen.perform(output, new File(location).getParentFile());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDimensionServiceKey() {
|
||||
return getClass().getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.util.dom.generator.DomGenPanel">
|
||||
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="6" column-count="3" 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="437" height="199"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title="Dom Generator Config"/>
|
||||
<children>
|
||||
<component id="29b47" 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="Namespace:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="1b788">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<vspacer id="e8ccd">
|
||||
<constraints>
|
||||
<grid row="5" 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="833b2" class="javax.swing.JTextField" binding="myNamespace">
|
||||
<constraints>
|
||||
<grid row="0" 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="7940e" 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="Schema File:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="7fb9d" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="mySchemaLocation" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="1" 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="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>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.fileChooser.FileTypeDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @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 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, "", myProject, new FileTypeDescriptor(title, "xsd", "dtd"));
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* XSD/DTD Model generator tool
|
||||
*
|
||||
* By Gregory Shrago
|
||||
* 2002 - 2006
|
||||
*/
|
||||
package com.intellij.util.dom.generator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface Emitter {
|
||||
public static final String JDOC_OPEN = "/**";
|
||||
public static final String JDOC_CONT = " * ";
|
||||
public static final String JDOC_CLOSE = " */";
|
||||
|
||||
|
||||
void emit(FileManager fileManager, ModelDesc model, File outputRoot);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface FileManager {
|
||||
public File releaseOutputFile(File outFile);
|
||||
public File getOutputFile(File target);
|
||||
}
|
||||
@@ -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 com.intellij.util.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,766 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
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;
|
||||
|
||||
|
||||
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");
|
||||
if (fd.required) {
|
||||
externalClasses.add("com.intellij.util.xml.Required");
|
||||
}
|
||||
if (fd.duplicateIndex >= 0 || fd.clType == FieldDesc.BOOL) {
|
||||
externalClasses.add("com.intellij.util.xml.SubTag");
|
||||
}
|
||||
if (fd.clType == FieldDesc.ATTR) {
|
||||
externalClasses.add("com.intellij.util.xml.GenericAttributeValue");
|
||||
} else if (Math.abs(fd.clType) != FieldDesc.SIMPLE) {
|
||||
if (Math.abs(fd.clType) == FieldDesc.OBJ) {
|
||||
final TypeDesc ftd = jtMap.get(fd.contentQualifiedName);
|
||||
if (ftd != null && ftd.type == TypeDesc.TypeEnum.ENUM) {
|
||||
externalClasses.add("com.intellij.util.xml.GenericDomValue");
|
||||
}
|
||||
} else {
|
||||
externalClasses.add("com.intellij.util.xml.GenericDomValue");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.");
|
||||
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);
|
||||
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;
|
||||
}
|
||||
});
|
||||
/*
|
||||
// fields
|
||||
out.println("");
|
||||
out.println("\t// fields");
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
out.print("\t// ");
|
||||
out.print(fields[i].tagName);
|
||||
out.print(", required:" + fields[i].required);
|
||||
out.print(", cltype:" + fields[i].clType);
|
||||
out.println("");
|
||||
String[] doc = parseAnnotationString(fields[i].documentation);
|
||||
for (int dc=0; dc<doc.length; dc++) {
|
||||
out.println("\t// "+doc[dc]);
|
||||
}
|
||||
|
||||
if (fields[i].comment != null) {
|
||||
out.print("\t// ");
|
||||
out.print(fields[i].comment);
|
||||
out.println("");
|
||||
}
|
||||
out.print("\tprivate ");
|
||||
out.print(fields[i].type);
|
||||
out.print(" ");
|
||||
out.print(fields[i].name);
|
||||
out.print(" = ");
|
||||
out.print(fields[i].def);
|
||||
out.print(";");
|
||||
out.println("");
|
||||
out.println("");
|
||||
}
|
||||
*/
|
||||
|
||||
// constructors
|
||||
|
||||
// set/get methods
|
||||
// static gets
|
||||
/*
|
||||
out.println("\t// standard getters");
|
||||
out.println("\t" + JDOC_OPEN);
|
||||
out.println("\t" + JDOC_CONT + "Returns \"" + defTagName + "\"");
|
||||
out.println("\t" + JDOC_CLOSE);
|
||||
out.println("\tpublic String get_tag_name() { return _tag_name; }");
|
||||
out.println("\t" + JDOC_OPEN);
|
||||
out.println("\t" + JDOC_CONT + "Returns child node tag names");
|
||||
out.println("\t" + JDOC_CLOSE);
|
||||
out.println("\tpublic String[] get_tag_names() { return (String[])_tag_names.clone(); }");
|
||||
out.println("\t" + JDOC_OPEN);
|
||||
out.println("\t" + JDOC_CONT + "Returns child node field names");
|
||||
out.println("\t" + JDOC_CLOSE);
|
||||
out.println("\tpublic String[] get_field_names() { return (String[])_field_names.clone(); }");
|
||||
out.println("");
|
||||
out.println("\t// getters/setters methods");
|
||||
*/
|
||||
|
||||
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@com.intellij.util.xml.Attribute (\"").append(tagName).append("\")");
|
||||
} else if (isList) {
|
||||
// sbAnnotations.append((JB_OFF ? "//" : "") +"\t@SubTagList (\"" + tagName + "\")");
|
||||
if (nameChanged) {
|
||||
sbAnnotations.append((JB_OFF ? "//" : "") + "\t@com.intellij.util.xml.SubTag (\"").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@com.intellij.util.xml.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("();");
|
||||
/*
|
||||
if (!td.isGroupInterface) {
|
||||
out.println("\t" + JDOC_OPEN);
|
||||
out.println("\t" + JDOC_CONT + "Adds new child to the list of " + javaDocTagName + ".");
|
||||
out.println("\t" + JDOC_CONT + "@param " + paramName + " the new child to add");
|
||||
out.println("\t" + JDOC_CLOSE);
|
||||
if (sbAnnotations.length() > 0) out.println(sbAnnotations);
|
||||
}
|
||||
out.print("\tpublic void add");
|
||||
out.print(capitalize(fields[i].elementName));
|
||||
out.print("(");
|
||||
out.print(fields[i].elementType);
|
||||
out.print(" ");
|
||||
out.print(paramName);
|
||||
out.println(");");
|
||||
|
||||
if (!td.isGroupInterface) {
|
||||
out.println("\t" + JDOC_OPEN);
|
||||
out.println("\t" + JDOC_CONT + "Removes the child from the list of " + javaDocTagName + ".");
|
||||
out.println("\t" + JDOC_CONT + "@param " + paramName + " the new child to remove");
|
||||
out.println("\t" + JDOC_CLOSE);
|
||||
if (sbAnnotations.length() > 0) out.println(sbAnnotations);
|
||||
}
|
||||
out.print("\tpublic ");
|
||||
out.print("void remove");
|
||||
out.print(capitalize(fields[i].elementName));
|
||||
out.print("(");
|
||||
out.print(fields[i].elementType);
|
||||
out.print(" ");
|
||||
out.print(paramName);
|
||||
out.println(");");
|
||||
*/
|
||||
}
|
||||
|
||||
out.println("");
|
||||
out.println("");
|
||||
}
|
||||
out.println("}");
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
out.close();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
fileManager.releaseOutputFile(outFile);
|
||||
}
|
||||
}
|
||||
|
||||
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.");
|
||||
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.");
|
||||
out.println(JDOC_CLOSE);
|
||||
out.print("public class " + typeName + " ");
|
||||
out.println("{");
|
||||
out.println("");
|
||||
|
||||
// child index method
|
||||
// class Holder implements Comparable {
|
||||
// String str;
|
||||
// int index;
|
||||
//
|
||||
// public Holder(String str, int index) {
|
||||
// this.str = str;
|
||||
// this.index = index;
|
||||
// }
|
||||
//
|
||||
// public int compareTo(Object o) {
|
||||
// return str.compareTo(o==null?null:((Holder)o).str);
|
||||
// }
|
||||
// };
|
||||
// ArrayList holders = new ArrayList();
|
||||
// for (Iterator it = jtList.iterator(); it.hasNext();) {
|
||||
// TypeDesc td = (TypeDesc) it.next();
|
||||
// NamespaceDesc tdnsd = (NamespaceDesc) nsdMap.get(td.xsNamespace);
|
||||
// String qname = toJavaQualifiedTypeName(tdnsd, td.name);
|
||||
// ArrayList fields = new ArrayList(td.fdMap.values());
|
||||
// Collections.sort(fields, new Comparator() {
|
||||
// public int compare(Object o1, Object o2) {
|
||||
// return ((FieldDesc) o1).realIndex - ((FieldDesc) o2).realIndex;
|
||||
// }
|
||||
// });
|
||||
// for (Iterator it2 = fields.iterator(); it2.hasNext();) {
|
||||
// FieldDesc fd = (FieldDesc) it2.next();
|
||||
// Holder h = new Holder(qname+":"+fd.tagName, fd.realIndex);
|
||||
// holders.add(h);
|
||||
// }
|
||||
// }
|
||||
// Collections.sort(holders);
|
||||
// out.println("\tprivate static String[] parentChildTags = new String[] {");
|
||||
// int idx = 0;
|
||||
// for (Iterator it = holders.iterator(); it.hasNext(); idx++) {
|
||||
// Holder holder = (Holder) it.next();
|
||||
// if (idx % 4 == 0) out.print("\n\t\t");
|
||||
// out.print("\""+holder.str+"\"");
|
||||
// if (idx < holders.size()-1) out.print(",");
|
||||
// }
|
||||
// out.println("\n\t};");
|
||||
// out.println("\tprivate static int[] parentChildIndices = new int[] {");
|
||||
// idx = 0;
|
||||
// for (Iterator it = holders.iterator(); it.hasNext(); idx++) {
|
||||
// Holder holder = (Holder) it.next();
|
||||
// if (idx % 24 == 0) out.print("\n\t\t");
|
||||
// out.print(holder.index);
|
||||
// if (idx < holders.size()-1) out.print(",");
|
||||
// }
|
||||
// out.println("\n\t};");
|
||||
// out.println();
|
||||
// out.println("\tpublic static int getChildIndex(String parentTag, String childTag) {");
|
||||
// out.println("\t\tint idx = java.util.Arrays.binarySearch(parentChildTags, parentTag+\":\"+childTag);");
|
||||
// out.println("\t\treturn idx < 0? -1: parentChildIndices[idx];");
|
||||
// out.println("\t}");
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
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 = merged.toArray(new String[merged.size()]);
|
||||
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 new String[0];
|
||||
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 list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import org.apache.xerces.xs.XSObject;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
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.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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.apache.xerces.xni.parser.XMLEntityResolver;
|
||||
import org.apache.xerces.xni.parser.XMLInputSource;
|
||||
import org.apache.xerces.xni.XMLResourceIdentifier;
|
||||
import org.apache.xerces.xni.XNIException;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.CharArrayReader;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
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) {
|
||||
schemaLocationMap.put(schema, location);
|
||||
model.nsdMap.put("http://www.w3.org/2001/XMLSchema", new NamespaceDesc("http://www.w3.org/2001/XMLSchema"));
|
||||
model.nsdMap.put("http://www.w3.org/2001/XMLSchema-instance", new NamespaceDesc("http://www.w3.org/2001/XMLSchema-instance"));
|
||||
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 = list.toArray(new String[list.size()]);
|
||||
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;
|
||||
final String fileName = esid.substring(esid.lastIndexOf('/') + 1);
|
||||
f = new File(root, fileName);
|
||||
}
|
||||
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) {
|
||||
files.addAll(Arrays.asList(root.listFiles()));
|
||||
}
|
||||
loader.loadModel(model, files, resolver);
|
||||
Util.log(model.jtMap.size() + " java types loaded");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import org.apache.xerces.xni.parser.XMLEntityResolver;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface ModelLoader {
|
||||
void loadModel(ModelDesc model, Collection<File> files, XMLEntityResolver resolver) throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
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 + ";";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* 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 com.intellij.util.dom.generator;
|
||||
|
||||
import org.apache.xerces.xs.XSObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,674 @@
|
||||
/*
|
||||
* 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 com.intellij.util.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
|
||||
*/
|
||||
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())) {
|
||||
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 ("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);
|
||||
}
|
||||
}
|
||||
choice[i] = fd;
|
||||
choice[i].choice = choice;
|
||||
if (fd.required) choiceOpt = false;
|
||||
}
|
||||
for (i = 0; i < choice.length; i++) {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,25 @@ public abstract class DomChildDescriptionImpl extends AbstractDomChildDescriptio
|
||||
myTagName = tagName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myTagName.getLocalName();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void navigate(boolean requestFocus) {
|
||||
}
|
||||
|
||||
public boolean canNavigate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canNavigateToSource() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getXmlElementName() {
|
||||
return myTagName.getLocalName();
|
||||
|
||||
@@ -17,9 +17,9 @@ package com.intellij.xml.impl.dom;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.references.PomService;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.FakePsiElement;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
@@ -204,11 +204,7 @@ public class DomElementXmlDescriptor implements XmlElementDescriptor {
|
||||
|
||||
if (declaration != null) return declaration.getXmlElement();
|
||||
|
||||
return new FakePsiElement() {
|
||||
public PsiElement getParent() {
|
||||
return DomUtil.getFile(mySomeElement);
|
||||
}
|
||||
};
|
||||
return PomService.convertToPsi(myManager.getProject(), myChildrenDescription);
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@@ -255,6 +251,25 @@ public class DomElementXmlDescriptor implements XmlElementDescriptor {
|
||||
myDomElement = domElement;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return getXmlElementName();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void navigate(boolean requestFocus) {
|
||||
}
|
||||
|
||||
public boolean canNavigate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canNavigateToSource() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public XmlName getXmlName() {
|
||||
throw new UnsupportedOperationException("Method getXmlName not implemented in " + getClass());
|
||||
@@ -304,4 +319,5 @@ public class DomElementXmlDescriptor implements XmlElementDescriptor {
|
||||
throw new UnsupportedOperationException("Method getAnnotation not implemented in " + getClass());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.util.xml.reflect;
|
||||
|
||||
import com.intellij.pom.PomNamedTarget;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomNameStrategy;
|
||||
import com.intellij.util.xml.XmlName;
|
||||
@@ -23,7 +24,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public interface DomChildrenDescription extends AbstractDomChildrenDescription {
|
||||
public interface DomChildrenDescription extends AbstractDomChildrenDescription, PomNamedTarget {
|
||||
|
||||
@NotNull
|
||||
XmlName getXmlName();
|
||||
|
||||
Reference in New Issue
Block a user