diff --git a/bin/win/IdeaWin32.dll b/bin/win/IdeaWin32.dll index c6675b1b1f3b..7556f14f2411 100644 Binary files a/bin/win/IdeaWin32.dll and b/bin/win/IdeaWin32.dll differ diff --git a/bin/win/IdeaWin64.dll b/bin/win/IdeaWin64.dll index 7f49282219c8..fe26d4a930db 100644 Binary files a/bin/win/IdeaWin64.dll and b/bin/win/IdeaWin64.dll differ diff --git a/build/update.sh b/build/update.sh index cc2471313c2e..61f009e28087 100755 --- a/build/update.sh +++ b/build/update.sh @@ -9,7 +9,7 @@ # 3. DEV_IDEA_HOME points to the directory of the project you built at step 1 # 4. You quit IntelliJ IDEA -if [ ! -f "$WORK_IDEA_HOME/bin/idea.sh" ]; then +if [ ! -f "$WORK_IDEA_HOME/bin/inspect.sh" ]; then echo "WORK_IDEA_HOME must be defined and point to build you're updating." exit fi diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java index 3e7011576e30..c3896a82a472 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java @@ -38,6 +38,9 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.serialization.artifact.ArtifactManagerState; +import org.jetbrains.jps.model.serialization.artifact.ArtifactPropertiesState; +import org.jetbrains.jps.model.serialization.artifact.ArtifactState; import java.util.*; diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerStateSplitter.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerStateSplitter.java index 7525b85843f2..90ee240c0a04 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerStateSplitter.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerStateSplitter.java @@ -21,6 +21,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.text.UniqueNameGenerator; import org.jdom.Element; +import org.jetbrains.jps.model.serialization.artifact.ArtifactState; import java.util.ArrayList; import java.util.List; diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java index 6f25a287f881..c6df02ec5188 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java @@ -16,6 +16,7 @@ package com.intellij.packaging.impl.artifacts; import com.intellij.packaging.elements.PackagingElementFactory; +import org.jetbrains.jps.model.serialization.artifact.ArtifactState; /** * @author nik diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java index e1ddd27d7cb8..0dca4cba3191 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java @@ -18,9 +18,9 @@ package com.intellij.packaging.impl.elements; import com.intellij.openapi.compiler.CompilerBundle; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.packaging.elements.CompositePackagingElementType; +import com.intellij.packaging.impl.artifacts.ArtifactUtil; import com.intellij.packaging.impl.ui.properties.ArchiveElementPropertiesPanel; import com.intellij.packaging.ui.ArtifactEditorContext; import com.intellij.packaging.ui.PackagingElementPropertiesPanel; @@ -53,7 +53,7 @@ class ArchiveElementType extends CompositePackagingElementType= 4 && name.charAt(name.length() - 4) == '.' && StringUtil.endsWithIgnoreCase(name, "ar")) { + if (ArtifactUtil.isArchiveName(name)) { return new ArchiveElementPropertiesPanel(element, context); } return null; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java index 78a87644b8ed..af6dc31c8482 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java @@ -30,6 +30,9 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; +import static com.intellij.patterns.PsiJavaPatterns.psiClass; +import static com.intellij.patterns.PsiJavaPatterns.psiElement; + /** * @author peter */ @@ -37,17 +40,24 @@ public class JavaNoVariantsDelegator extends CompletionContributor { @Override public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { - final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true)); + final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true)) || + suggestMetaAnnotations(parameters); if (!empty && parameters.getInvocationCount() == 0) { result.restartCompletionWhenNothingMatches(); } if (empty) { - delegate(parameters, result); + delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result)); } } + private static boolean suggestMetaAnnotations(CompletionParameters parameters) { + PsiElement position = parameters.getPosition(); + return psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class, PsiModifierList.class, PsiClass.class).accepts( position) && + psiElement().withSuperParent(4, psiClass().isAnnotationType()).accepts(position); + } + public static boolean containsOnlyPackages(LinkedHashSet results) { for (CompletionResult result : results) { if (!(CompletionUtil.getTargetElement(result.getLookupElement()) instanceof PsiPackage)) { @@ -152,7 +162,7 @@ public class JavaNoVariantsDelegator extends CompletionContributor { final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result); JavaClassNameCompletionContributor.addAllClasses(parameters, - true, JavaCompletionSorting.addJavaSorting(parameters, result).getPrefixMatcher(), new Consumer() { + true, result.getPrefixMatcher(), new Consumer() { @Override public void consume(LookupElement element) { JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java index 7e9c4d7a920e..1465616183b2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java @@ -18,16 +18,17 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementWeigher; +import com.intellij.openapi.util.Condition; import com.intellij.patterns.ElementPattern; import com.intellij.psi.*; import com.intellij.psi.filters.getters.MembersGetter; import com.intellij.psi.impl.source.tree.JavaElementType; +import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PropertyUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Set; @@ -55,26 +56,60 @@ public class PreferByKindWeigher extends LookupElementWeigher { private final CompletionType myCompletionType; private final PsiElement myPosition; private final Set myNonInitializedFields; - @Nullable private final String myRequiredSuper; + @NotNull private final Condition myRequiredSuper; - public PreferByKindWeigher(CompletionType completionType, PsiElement position) { + public PreferByKindWeigher(CompletionType completionType, final PsiElement position) { super("local"); myCompletionType = completionType; myPosition = position; myNonInitializedFields = JavaCompletionProcessor.getNonInitializedFields(position); + myRequiredSuper = createSuitabilityCondition(position); + } + private static Condition createSuitabilityCondition(final PsiElement position) { if (IN_CATCH_TYPE.accepts(position) || IN_MULTI_CATCH_TYPE.accepts(position) || JavaSmartCompletionContributor.AFTER_THROW_NEW.accepts(position) || INSIDE_METHOD_THROWS_CLAUSE.accepts(position)) { - myRequiredSuper = CommonClassNames.JAVA_LANG_THROWABLE; + return new Condition() { + @Override + public boolean value(PsiClass psiClass) { + return InheritanceUtil.isInheritor(psiClass, CommonClassNames.JAVA_LANG_THROWABLE); + } + }; } - else if (IN_RESOURCE_TYPE.accepts(position)) { - myRequiredSuper = CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE; + + if (IN_RESOURCE_TYPE.accepts(position)) { + return new Condition() { + @Override + public boolean value(PsiClass psiClass) { + return InheritanceUtil.isInheritor(psiClass, CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE); + } + }; } - else { - myRequiredSuper = null; + + if (psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class).accepts(position)) { + final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(position, PsiAnnotation.class); + assert annotation != null; + PsiAnnotationOwner owner = annotation.getOwner(); + if (owner instanceof PsiModifierList || owner instanceof PsiTypeElement || + owner instanceof PsiMethodReceiver || owner instanceof PsiTypeParameter) { + PsiElement member = ((PsiElement)owner).getParent(); + final String[] elementTypeFields = PsiAnnotationImpl + .getApplicableElementTypeFields(owner instanceof PsiModifierList ? member : (PsiElement)owner); + return new Condition() { + @Override + public boolean value(PsiClass psiClass) { + if (!psiClass.isAnnotationType()) { + return false; + } + return PsiAnnotationImpl.isAnnotationApplicable(false, psiClass, elementTypeFields, position.getResolveScope()); + } + }; + } } + //noinspection unchecked + return Condition.FALSE; } enum MyResult { @@ -156,7 +191,7 @@ public class PreferByKindWeigher extends LookupElementWeigher { } if (object instanceof PsiClass) { - if (myRequiredSuper != null && InheritanceUtil.isInheritor((PsiClass)object, myRequiredSuper)) { + if (myRequiredSuper.value((PsiClass)object)) { return MyResult.suitableClass; } return MyResult.classNameOrGlobalStatic; diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java index b1672bd395f3..1ba18d7f49ce 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java @@ -226,7 +226,7 @@ public class PsiTypeLookupItem extends LookupItem { } if (myBracketsCount > 0) { - presentation.setTailText(StringUtil.repeat("[]", myBracketsCount) + presentation.getTailText(), true); + presentation.setTailText(StringUtil.repeat("[]", myBracketsCount) + StringUtil.notNullize(presentation.getTailText()), true); } } diff --git a/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesAction.java b/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesAction.java index cd222246348c..77c39c581c2f 100644 --- a/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesAction.java +++ b/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesAction.java @@ -21,7 +21,8 @@ import com.intellij.analysis.JavaAnalysisScope; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.psi.*; @@ -49,7 +50,8 @@ public class CyclicDependenciesAction extends AnAction{ public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); presentation.setEnabled( - getInspectionScope(event.getDataContext()) != null || event.getData(LangDataKeys.PSI_FILE) != null); + getInspectionScope(event.getDataContext()) != null || + event.getData(PlatformDataKeys.PROJECT) != null); } public void actionPerformed(AnActionEvent e) { @@ -57,15 +59,11 @@ public class CyclicDependenciesAction extends AnAction{ final Project project = PlatformDataKeys.PROJECT.getData(dataContext); final Module module = LangDataKeys.MODULE.getData(dataContext); if (project != null) { - PsiFile psiFile = LangDataKeys.PSI_FILE.getData(dataContext); - if (psiFile != null && !(psiFile instanceof PsiJavaFile)) { - return; - } AnalysisScope scope = getInspectionScope(dataContext); if (scope == null || scope.getScopeType() != AnalysisScope.MODULES){ ProjectModuleOrPackageDialog dlg = null; if (module != null) { - dlg = new ProjectModuleOrPackageDialog(ModuleUtil.getModuleNameInReadAction(module), scope); + dlg = new ProjectModuleOrPackageDialog(ModuleManager.getInstance(project).getModules().length == 1 ? null : ModuleUtilCore.getModuleNameInReadAction(module), scope); dlg.show(); if (!dlg.isOK()) return; } @@ -104,12 +102,12 @@ public class CyclicDependenciesAction extends AnAction{ //Possible scopes: package, project, module. Project projectContext = PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext); if (projectContext != null) { - return new AnalysisScope(projectContext); + return null; } Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext); if (moduleContext != null) { - return new AnalysisScope(moduleContext); + return null; } Module [] modulesArray = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); @@ -128,12 +126,9 @@ public class CyclicDependenciesAction extends AnAction{ PsiDirectory[] dirs = pack.getDirectories(GlobalSearchScope.projectScope(pack.getProject())); if (dirs.length == 0) return null; return new JavaAnalysisScope(pack, LangDataKeys.MODULE.getData(dataContext)); - } else if (psiTarget != null){ - return null; } - - return getProjectScope(dataContext); + return null; } @Nullable @@ -173,7 +168,6 @@ public class CyclicDependenciesAction extends AnAction{ init(); setTitle(AnalysisScopeBundle.message("cyclic.dependencies.scope.dialog.title", myTitle)); setHorizontalStretch(1.75f); - myModuleButton.setSelected(true); } public boolean isIncludeTestSources() { @@ -190,11 +184,19 @@ public class CyclicDependenciesAction extends AnAction{ myModuleButton.setText(AnalysisScopeBundle.message("cyclic.dependencies.scope.dialog.module.button", myAnalysisVerb, myModuleName)); group.add(myModuleButton); } + myModuleButton.setVisible(myModuleName != null); mySelectedScopeButton.setVisible(mySelectedScope != null); if (mySelectedScope != null) { mySelectedScopeButton.setText(mySelectedScope.getShortenName()); group.add(mySelectedScopeButton); } + if (mySelectedScope != null) { + mySelectedScopeButton.setSelected(true); + } else if (myModuleName != null) { + myModuleButton.setSelected(true); + } else { + myProjectButton.setSelected(true); + } return myWholePanel; } diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java new file mode 100644 index 000000000000..2ba78bf98153 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java @@ -0,0 +1,195 @@ +/* + * Copyright 2000-2012 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.psi.codeStyle.arrangement; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType; +import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; +import com.intellij.util.containers.Stack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class JavaArrangementVisitor extends JavaElementVisitor { + + private static final Map MODIFIERS = new HashMap(); + static { + MODIFIERS.put(PsiModifier.PUBLIC, ArrangementModifier.PUBLIC); + MODIFIERS.put(PsiModifier.PROTECTED, ArrangementModifier.PROTECTED); + MODIFIERS.put(PsiModifier.PRIVATE, ArrangementModifier.PRIVATE); + MODIFIERS.put(PsiModifier.PACKAGE_LOCAL, ArrangementModifier.PACKAGE_PRIVATE); + MODIFIERS.put(PsiModifier.STATIC, ArrangementModifier.STATIC); + MODIFIERS.put(PsiModifier.FINAL, ArrangementModifier.FINAL); + } + + private final Stack myStack = new Stack(); + + @NotNull private final List myRootEntries; + @NotNull private Document myDocument; + @NotNull private Collection myRanges; + + public JavaArrangementVisitor(@NotNull List entries, + @NotNull Document document, + @NotNull Collection ranges) + { + myRootEntries = entries; + myDocument = document; + myRanges = ranges; + } + + @Override + public void visitClass(PsiClass aClass) { + JavaElementArrangementEntry entry = createNewEntry(aClass.getTextRange(), ArrangementEntryType.CLASS, aClass.getName(), true); + processEntry(entry, aClass, aClass); + } + + @Override + public void visitAnonymousClass(PsiAnonymousClass aClass) { + JavaElementArrangementEntry entry = createNewEntry(aClass.getTextRange(), ArrangementEntryType.CLASS, aClass.getName(), false); + processEntry(entry, null, aClass); + } + + @Override + public void visitJavaFile(PsiJavaFile file) { + for (PsiClass psiClass : file.getClasses()) { + visitClass(psiClass); + } + } + + @Override + public void visitField(PsiField field) { + JavaElementArrangementEntry entry = createNewEntry(field.getTextRange(), ArrangementEntryType.FIELD, field.getName(), true); + processEntry(entry, field, field.getInitializer()); + } + + @Override + public void visitMethod(PsiMethod method) { + JavaElementArrangementEntry entry = createNewEntry(method.getTextRange(), ArrangementEntryType.METHOD, method.getName(), true); + processEntry(entry, method, method.getBody()); + } + + @Override + public void visitExpressionStatement(PsiExpressionStatement statement) { + statement.getExpression().acceptChildren(this); + } + + @Override + public void visitNewExpression(PsiNewExpression expression) { + PsiAnonymousClass anonymousClass = expression.getAnonymousClass(); + if (anonymousClass == null) { + return; + } + JavaElementArrangementEntry entry = + createNewEntry(anonymousClass.getTextRange(), ArrangementEntryType.CLASS, anonymousClass.getName(), false); + processEntry(entry, null, anonymousClass); + } + + @Override + public void visitExpressionList(PsiExpressionList list) { + for (PsiExpression expression : list.getExpressions()) { + expression.acceptChildren(this); + } + } + + @Override + public void visitDeclarationStatement(PsiDeclarationStatement statement) { + for (PsiElement element : statement.getDeclaredElements()) { + element.acceptChildren(this); + } + } + + private void processEntry(@Nullable JavaElementArrangementEntry entry, + @Nullable PsiModifierListOwner modifier, + @Nullable PsiElement nextPsiRoot) + { + if (entry == null) { + return; + } + if (modifier != null) { + parseModifiers(modifier.getModifierList(), entry); + } + if (nextPsiRoot == null) { + return; + } + myStack.push(entry); + try { + nextPsiRoot.acceptChildren(this); + } + finally { + myStack.pop(); + } + } + + @Nullable + private JavaElementArrangementEntry createNewEntry(@NotNull TextRange range, + @NotNull ArrangementEntryType type, + @Nullable String name, + boolean canArrange) + { + if (!isWithinBounds(range)) { + return null; + } + DefaultArrangementEntry current = getCurrent(); + JavaElementArrangementEntry entry; + if (canArrange) { + TextRange expandedRange = ArrangementUtil.expandToLine(range, myDocument.getCharsSequence()); + TextRange rangeToUse = expandedRange == null ? range : expandedRange; + entry = new JavaElementArrangementEntry(current, rangeToUse, type, name, expandedRange != null); + } + else { + entry = new JavaElementArrangementEntry(current, range, type, name, false); + } + if (current == null) { + myRootEntries.add(entry); + } + else { + current.addChild(entry); + } + + return entry; + } + + private boolean isWithinBounds(@NotNull TextRange range) { + for (TextRange textRange : myRanges) { + if (textRange.intersects(range)) { + return true; + } + } + return false; + } + + @Nullable + private DefaultArrangementEntry getCurrent() { + return myStack.isEmpty() ? null : myStack.peek(); + } + + private static void parseModifiers(@Nullable PsiModifierList modifierList, @NotNull JavaElementArrangementEntry entry) { + if (modifierList == null) { + return; + } + for (String modifier : PsiModifier.MODIFIERS) { + if (modifierList.hasModifierProperty(modifier)) { + entry.addModifier(MODIFIERS.get(modifier)); + } + } + } +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaElementArrangementEntry.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaElementArrangementEntry.java new file mode 100644 index 000000000000..75e243feeb92 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaElementArrangementEntry.java @@ -0,0 +1,93 @@ +/* + * Copyright 2000-2012 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.psi.codeStyle.arrangement; + +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType; +import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; +import com.intellij.psi.codeStyle.arrangement.match.ModifierAwareArrangementEntry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.EnumSet; +import java.util.Set; + +/** + * @author Denis Zhdanov + * @since 7/20/12 4:50 PM + */ +public class JavaElementArrangementEntry extends DefaultArrangementEntry + implements TypeAwareArrangementEntry, NameAwareArrangementEntry,ModifierAwareArrangementEntry +{ + + private final Set myModifiers = EnumSet.noneOf(ArrangementModifier.class); + + @NotNull private final ArrangementEntryType myType; + @Nullable private final String myName; + + public JavaElementArrangementEntry(@Nullable ArrangementEntry parent, + @NotNull TextRange range, + @NotNull ArrangementEntryType type, + @Nullable String name, + boolean canBeMatched) + { + this(parent, range.getStartOffset(), range.getEndOffset(), type, name, canBeMatched); + } + + public JavaElementArrangementEntry(@Nullable ArrangementEntry parent, + int startOffset, + int endOffset, + @NotNull ArrangementEntryType type, + @Nullable String name, + boolean canBeArranged) + { + super(parent, startOffset, endOffset, canBeArranged); + myType = type; + myName = name; + } + + @NotNull + @Override + public Set getModifiers() { + return myModifiers; + } + + public void addModifier(@NotNull ArrangementModifier modifier) { + myModifiers.add(modifier); + } + + @Nullable + @Override + public String getName() { + return myName; + } + + @NotNull + @Override + public ArrangementEntryType getType() { + return myType; + } + + @Override + public String toString() { + return String.format( + "[%d; %d): %s %s %s", + getStartOffset(), getEndOffset(), StringUtil.join(myModifiers, " ").toLowerCase(), myType.toString().toLowerCase(), + myName == null ? "" : myName + ); + } +} diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java new file mode 100644 index 000000000000..a4124104df51 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2012 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.psi.codeStyle.arrangement; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author Denis Zhdanov + * @since 7/20/12 2:31 PM + */ +public class JavaRearranger implements Rearranger { + + @NotNull + @Override + public Collection parse(@NotNull PsiElement root, + @NotNull Document document, + @NotNull Collection ranges) + { + // Following entries are subject to arrangement: class, interface, field, method. + List result = new ArrayList(); + root.accept(new JavaArrangementVisitor(result, document, ranges)); + return result; + } +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java index b6fe75031c4e..047e0182facf 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java @@ -162,14 +162,17 @@ public class PsiAnnotationImpl extends JavaStubPsiElement imp return !strict; } PsiClass annotationType = (PsiClass)resolved; - return isAnnotationApplicable(strict, annotationType, elementTypeFields, annotation.getManager(), annotation.getResolveScope()); + return isAnnotationApplicable(strict, annotationType, elementTypeFields, annotation.getResolveScope()); } public static boolean isAnnotationApplicable(boolean strict, - PsiClass annotationType, - String[] elementTypeFields, - PsiManager manager, + @NotNull PsiClass annotationType, + @Nullable String[] elementTypeFields, GlobalSearchScope resolveScope) { + if (elementTypeFields == null) { + return !strict; + } + PsiAnnotation target = annotationType.getModifierList().findAnnotation(CommonClassNames.TARGET_ANNOTATION_FQ_NAME); if (target == null) { //todo hack: ambiguity in spec @@ -183,7 +186,8 @@ public class PsiAnnotationImpl extends JavaStubPsiElement imp PsiAnnotationMemberValue value = attributes[0].getValue(); LOG.assertTrue(elementTypeFields.length > 0); - PsiClass elementTypeClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.annotation.ElementType", resolveScope); + PsiClass elementTypeClass = + JavaPsiFacade.getInstance(annotationType.getProject()).findClass("java.lang.annotation.ElementType", resolveScope); if (elementTypeClass == null) { //todo hack return !strict; @@ -192,17 +196,23 @@ public class PsiAnnotationImpl extends JavaStubPsiElement imp for (String fieldName : elementTypeFields) { PsiField field = elementTypeClass.findFieldByName(fieldName, false); - if (field == null) continue; + if (field == null) { + continue; + } if (value instanceof PsiArrayInitializerMemberValue) { PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)value).getInitializers(); for (PsiAnnotationMemberValue initializer : initializers) { if (initializer instanceof PsiReference) { - if (((PsiReference)initializer).isReferenceTo(field)) return true; + if (((PsiReference)initializer).isReferenceTo(field)) { + return true; + } } } } else if (value instanceof PsiReference) { - if (((PsiReference)value).isReferenceTo(field)) return true; + if (((PsiReference)value).isReferenceTo(field)) { + return true; + } } } return false; diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/PreferApplicableAnnotations.java b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferApplicableAnnotations.java new file mode 100644 index 000000000000..fe6080708ee9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferApplicableAnnotations.java @@ -0,0 +1,2 @@ +@T +@interface Foo { } diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray.java b/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray.java new file mode 100644 index 000000000000..f0cdb7199549 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray.java @@ -0,0 +1,5 @@ +class A { + byte[] m() { + return new x; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy index a5797213a6c9..df1588a69eab 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy @@ -342,6 +342,19 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { checkPreferredItems 0, 'serial', 'superExpressionInIllegalContext' } + public void testPreferApplicableAnnotations() throws Throwable { + myFixture.addClass ''' +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ElementType.ANNOTATION_TYPE}) +@interface TMetaAnno {} + +@Target({ElementType.LOCAL_VARIABLE}) +@interface TLocalAnno {}''' + checkPreferredItems 0, 'TMetaAnno', 'Target', 'TreeSelectionMode', 'TLocalAnno' + } + public void testJComponentAddNewWithStats() throws Throwable { final LookupImpl lookup = invokeCompletion("/../smartTypeSorting/JComponentAddNew.java"); assertPreferredItems(0, "FooBean3", "JComponent", "Component"); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index 22e8b463b992..9d8703dca517 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -612,6 +612,13 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { assertEquals("[] (java.lang)", LookupElementPresentation.renderElement(myItems[1]).getTailText()); } + public void testNewByteArray() { + configureByTestName(); + assertStringItems("byte"); + assertEquals("[]", LookupElementPresentation.renderElement(myItems[0]).getTailText()); + + } + public void testInsideStringLiteral() throws Throwable { doAntiTest(); } public void testDefaultAnnoParam() throws Throwable { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/AbstractRearrangerTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/AbstractRearrangerTest.groovy new file mode 100644 index 000000000000..8d2a19cee7cf --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/AbstractRearrangerTest.groovy @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2012 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.psi.codeStyle.arrangement + +import com.intellij.lang.java.JavaLanguage +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.fileTypes.FileType +import com.intellij.openapi.util.TextRange +import com.intellij.psi.codeStyle.CodeStyleSettings +import com.intellij.psi.codeStyle.CodeStyleSettingsManager +import com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull +import org.jetbrains.annotations.Nullable +/** + * @author Denis Zhdanov + * @since 7/20/12 2:54 PM + */ +abstract class AbstractRearrangerTest extends LightCodeInsightFixtureTestCase { + + def FileType fileType + + @Override + protected void setUp() { + super.setUp() + CodeStyleSettingsManager.getInstance(myFixture.project).temporarySettings = new CodeStyleSettings() + } + + @Override + protected void tearDown() { + CodeStyleSettingsManager.getInstance(myFixture.project).dropTemporarySettings() + super.tearDown() + } + + protected void doTest(@NotNull String initial, + @NotNull String expected, + @NotNull List rules, + Collection ranges = null) + { + def (String textToUse, List rangesToUse) = parseRanges(initial) + if (rangesToUse && ranges) { + fail("Duplicate ranges info detected: explicitly given: $ranges, derived from markup: $rangesToUse. Text:\n$initial") + } + if (!rangesToUse) { + rangesToUse = ranges ?: [TextRange.from(0, initial.length())] + } + + myFixture.configureByText(fileType, textToUse) + def settings = CodeStyleSettingsManager.getInstance(myFixture.project).currentSettings.getCommonSettings(JavaLanguage.INSTANCE) + settings.arrangementRules = rules + ArrangementEngine engine = ServiceManager.getService(myFixture.project, ArrangementEngine) + engine.arrange(myFixture.file, rangesToUse); + assertEquals(expected, myFixture.editor.document.text); + } + + @NotNull + private static def parseRanges(@NotNull String text) { + def clearText = new StringBuilder(text) + def ranges = [] + int shift = 0 + int shiftIncrease = ''.length() * 2 + 1 + def match = text =~ '(?is).*?' + match.each { + ranges << TextRange.create(match.start() - shift, match.end() - shift - shiftIncrease) + clearText.delete(match.end() - ''.length() - shift, match.end() - shift) + clearText.delete(match.start() - shift, match.start() + ''.length() - shift) + shift += shiftIncrease + } + + [clearText.toString(), ranges] + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeTest.groovy new file mode 100644 index 000000000000..4642e9825c45 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeTest.groovy @@ -0,0 +1,178 @@ +/* + * Copyright 2000-2012 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.psi.codeStyle.arrangement + +import com.intellij.ide.highlighter.JavaFileType +import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType +import com.intellij.psi.codeStyle.arrangement.match.ByTypeArrangementEntryMatcher +/** + * @author Denis Zhdanov + * @since 7/20/12 2:45 PM + */ +class JavaRearrangerByTypeTest extends AbstractRearrangerTest { + + JavaRearrangerByTypeTest() { + fileType = JavaFileType.INSTANCE + } + + void testFieldsBeforeMethods() { + doTest( + '''\ +class Test { + public void test() {} + private int i; +} +class Test2 { +public void test() { +} + private int i; + private int j; +}''', + '''\ +class Test { + private int i; + public void test() {} +} +class Test2 { + private int i; + private int j; +public void test() { +} +}''', + [new ArrangementRule(new ByTypeArrangementEntryMatcher(ArrangementEntryType.FIELD))] + ) + } + + void testAnonymousClassAtFieldInitializer() { + doTest( + '''\ +class Test { + private Object first = new Object() { + int inner1; + public String toString() { return "test"; } + int inner2; + }; + public Object test(Object ... args) { + return null; + } + private Object second = test(test(new Object() { + public String toString() { + return "test"; + } + private Object inner = new Object() { + public String toString() { return "innerTest"; } + }; + })); +}''', + '''\ +class Test { + private Object first = new Object() { + int inner1; + int inner2; + public String toString() { return "test"; } + }; + private Object second = test(test(new Object() { + private Object inner = new Object() { + public String toString() { return "innerTest"; } + }; + public String toString() { + return "test"; + } + })); + public Object test(Object ... args) { + return null; + } +}''', + [new ArrangementRule(new ByTypeArrangementEntryMatcher(ArrangementEntryType.FIELD))] + ) + } + + void testAnonymousClassAtMethod() { + doTest( + '''\ +class Test { + void declaration() { + Object o = new Object() { + private int test() { return 1; } + String s; + } + } + double d; + void call() { + test(test(1, new Object() { + public void test() {} + int i; + }); + } +}''', + '''\ +class Test { + double d; + void declaration() { + Object o = new Object() { + String s; + private int test() { return 1; } + } + } + void call() { + test(test(1, new Object() { + int i; + public void test() {} + }); + } +}''', + [new ArrangementRule(new ByTypeArrangementEntryMatcher(ArrangementEntryType.FIELD))] + ) + } + + void testRanges() { + doTest( + '''\ +class Test { + void outer1() {} + String outer2() {} + int i; + void test() { + method(new Object() { + void inner1() {} + Object field = new Object() { + void inner2() {} + String s; + Integer i; + } + }); + } +}''', + '''\ +class Test { + void outer1() {} + int i; + String outer2() {} + void test() { + method(new Object() { + void inner1() {} + Object field = new Object() { + String s; + void inner2() {} + Integer i; + } + }); + } +}''', + [new ArrangementRule(new ByTypeArrangementEntryMatcher(ArrangementEntryType.FIELD))] + ) + } +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index e43cf4700b6a..d6c876de3856 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -17,7 +17,6 @@ import org.jetbrains.ether.dependencyView.Callbacks; import org.jetbrains.jps.JpsPathUtil; import org.jetbrains.jps.Project; import org.jetbrains.jps.api.*; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.idea.IdeaProjectLoader; import org.jetbrains.jps.idea.SystemOutErrorReporter; import org.jetbrains.jps.incremental.*; @@ -29,6 +28,8 @@ import org.jetbrains.jps.incremental.storage.ProjectTimestamps; import org.jetbrains.jps.incremental.storage.Timestamps; import org.jetbrains.jps.model.JpsElementFactory; import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.JpsArtifactService; import org.jetbrains.jps.model.java.JpsJavaLibraryType; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsOrderRootType; @@ -596,15 +597,13 @@ final class BuildSession implements Runnable, CanceledStatus { Collection artifactNames, Collection paths) throws Exception { final Timestamps timestamps = pd.timestamps.getStorage(); - Set artifacts = new HashSet(); + Set artifacts = new HashSet(); if (artifactNames.isEmpty() && buildType == BuildType.PROJECT_REBUILD) { - artifacts.addAll(pd.project.getArtifacts().values()); + artifacts.addAll(JpsArtifactService.getInstance().getArtifacts(pd.jpsProject)); } else { - final Map artifactMap = pd.project.getArtifacts(); - for (String name : artifactNames) { - final Artifact artifact = artifactMap.get(name); - if (artifact != null && !StringUtil.isEmpty(artifact.getOutputPath())) { + for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(pd.jpsProject)) { + if (artifactNames.contains(artifact.getName()) && !StringUtil.isEmpty(artifact.getOutputPath())) { artifacts.add(artifact); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/AllProjectScope.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/AllProjectScope.java index 2262090321dc..2506a5b293e8 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/AllProjectScope.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/AllProjectScope.java @@ -2,8 +2,8 @@ package org.jetbrains.jps.incremental; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.Project; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.JpsArtifact; import java.io.File; import java.util.Set; @@ -16,7 +16,7 @@ public class AllProjectScope extends CompileScope { private final boolean myIsForcedCompilation; - public AllProjectScope(Project project, JpsProject jpsProject, Set artifacts, boolean forcedCompilation) { + public AllProjectScope(Project project, JpsProject jpsProject, Set artifacts, boolean forcedCompilation) { super(project, jpsProject, artifacts); myIsForcedCompilation = forcedCompilation; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScope.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScope.java index a99c364b3587..f76334f75a12 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScope.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScope.java @@ -3,8 +3,8 @@ package org.jetbrains.jps.incremental; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.Project; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.JpsArtifact; import org.jetbrains.jps.model.module.JpsModule; import java.io.File; @@ -18,15 +18,15 @@ public abstract class CompileScope { @NotNull private final Project myProject; private final JpsProject myJpsProject; - private final Set myArtifacts; + private final Set myArtifacts; - protected CompileScope(@NotNull Project project, JpsProject jpsProject, Set artifacts) { + protected CompileScope(@NotNull Project project, JpsProject jpsProject, Set artifacts) { myProject = project; myJpsProject = jpsProject; myArtifacts = artifacts; } - public boolean isAffected(Artifact artifact) { + public boolean isAffected(JpsArtifact artifact) { return myArtifacts.contains(artifact); } @@ -45,7 +45,7 @@ public abstract class CompileScope { return false; } - public Set getArtifacts() { + public Set getArtifacts() { return myArtifacts; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModulesAndFilesScope.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModulesAndFilesScope.java index e3bebc8de50b..f46be3c90a17 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModulesAndFilesScope.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModulesAndFilesScope.java @@ -2,8 +2,8 @@ package org.jetbrains.jps.incremental; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.Project; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.JpsArtifact; import org.jetbrains.jps.model.module.JpsModule; import java.io.File; @@ -23,7 +23,7 @@ public class ModulesAndFilesScope extends CompileScope { private final boolean myForcedCompilation; public ModulesAndFilesScope(Project project, JpsProject jpsProject, Collection modules, Map> files, - Set artifacts, boolean isForcedCompilation) { + Set artifacts, boolean isForcedCompilation) { super(project, jpsProject, artifacts); myFiles = files; myForcedCompilation = isForcedCompilation; diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModulesScope.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModulesScope.java index e9dac3d97f5b..b00ec3522bdf 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModulesScope.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModulesScope.java @@ -2,8 +2,8 @@ package org.jetbrains.jps.incremental; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.Project; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.JpsArtifact; import org.jetbrains.jps.model.module.JpsModule; import java.io.File; @@ -19,7 +19,7 @@ public class ModulesScope extends CompileScope { private final Set myModules; private final boolean myForcedCompilation; - public ModulesScope(Project project, JpsProject jpsProject, Set modules, Set artifacts, boolean isForcedCompilation) { + public ModulesScope(Project project, JpsProject jpsProject, Set modules, Set artifacts, boolean isForcedCompilation) { super(project, jpsProject, artifacts); myModules = new HashSet(); for (JpsModule module : modules) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactSourceFilesState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactSourceFilesState.java index 16b97cee32cf..16424cd10169 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactSourceFilesState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactSourceFilesState.java @@ -6,8 +6,6 @@ import com.intellij.util.containers.IntArrayList; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.Project; import org.jetbrains.jps.ProjectPaths; -import org.jetbrains.jps.artifacts.Artifact; -import org.jetbrains.jps.artifacts.LayoutElement; import org.jetbrains.jps.incremental.ModuleRootsIndex; import org.jetbrains.jps.incremental.artifacts.builders.LayoutElementBuildersRegistry; import org.jetbrains.jps.incremental.artifacts.instructions.*; @@ -15,6 +13,8 @@ import org.jetbrains.jps.incremental.storage.BuildDataManager; import org.jetbrains.jps.incremental.storage.CompositeStorageOwner; import org.jetbrains.jps.incremental.storage.StorageOwner; import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; import java.io.File; import java.io.IOException; @@ -25,7 +25,7 @@ import java.util.*; */ public class ArtifactSourceFilesState extends CompositeStorageOwner { private final Project myProject; - private final Artifact myArtifact; + private final JpsArtifact myArtifact; private final int myArtifactId; private final JpsModel myModel; private final ModuleRootsIndex myRootsIndex; @@ -38,7 +38,7 @@ public class ArtifactSourceFilesState extends CompositeStorageOwner { private final File mySrcOutMappingsFile; private File myOutSrcMappingsFile; - public ArtifactSourceFilesState(Artifact artifact, int artifactId, Project project, + public ArtifactSourceFilesState(JpsArtifact artifact, int artifactId, Project project, JpsModel model, ModuleRootsIndex rootsIndex, ArtifactSourceTimestampStorage timestampStorage, File mappingsDir) { @@ -147,7 +147,7 @@ public class ArtifactSourceFilesState extends CompositeStorageOwner { } private ArtifactInstructionsBuilder computeInstructions() { - final LayoutElement rootElement = myArtifact.getRootElement(); + final JpsCompositePackagingElement rootElement = myArtifact.getRootElement(); ArtifactInstructionsBuilderContext context = new ArtifactInstructionsBuilderContextImpl(myProject, myModel, myRootsIndex, new ProjectPaths(myModel.getProject())); final ArtifactInstructionsBuilderImpl instructionsBuilder = new ArtifactInstructionsBuilderImpl(myRootsIndex, myProject.getIgnoredFilePatterns()); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactsBuildData.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactsBuildData.java index b86f841ac7ff..a9fbbab4efe0 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactsBuildData.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactsBuildData.java @@ -3,11 +3,11 @@ package org.jetbrains.jps.incremental.artifacts; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.jps.Project; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.incremental.ModuleRootsIndex; import org.jetbrains.jps.incremental.storage.CompositeStorageOwner; import org.jetbrains.jps.incremental.storage.StorageOwner; import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.artifact.JpsArtifact; import java.io.File; import java.io.IOException; @@ -19,14 +19,14 @@ import java.util.Map; * @author nik */ public class ArtifactsBuildData extends CompositeStorageOwner { - private Map myArtifactState; + private Map myArtifactState; private final ArtifactSourceTimestampStorage myTimestampStorage; private ArtifactCompilerPersistentData myPersistentData; private final File myMappingsDir; public ArtifactsBuildData(File artifactsDataDir) throws IOException { myTimestampStorage = new ArtifactSourceTimestampStorage(new File(artifactsDataDir, "timestamps")); - myArtifactState = new HashMap(); + myArtifactState = new HashMap(); myPersistentData = new ArtifactCompilerPersistentData(artifactsDataDir); myMappingsDir = new File(artifactsDataDir, "mappings"); if (myPersistentData.isVersionChanged()) { @@ -36,7 +36,7 @@ public class ArtifactsBuildData extends CompositeStorageOwner { } } - public ArtifactSourceFilesState getOrCreateState(Artifact artifact, Project project, JpsModel model, ModuleRootsIndex index) { + public ArtifactSourceFilesState getOrCreateState(JpsArtifact artifact, Project project, JpsModel model, ModuleRootsIndex index) { ArtifactSourceFilesState state = myArtifactState.get(artifact); if (state == null) { final int artifactId = myPersistentData.getId(artifact.getName()); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java index b818ddf0136b..19023797f523 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java @@ -6,7 +6,6 @@ import com.intellij.util.containers.IntArrayList; import com.intellij.util.containers.MultiMap; import gnu.trove.THashSet; import gnu.trove.TIntObjectHashMap; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.cmdline.ProjectDescriptor; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.ProjectBuildException; @@ -18,6 +17,8 @@ import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.CompilerMessage; import org.jetbrains.jps.incremental.messages.ProgressMessage; import org.jetbrains.jps.incremental.messages.UptoDateFilesSavedEvent; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.JpsArtifactService; import java.io.File; import java.io.IOException; @@ -35,32 +36,27 @@ public class IncArtifactBuilder extends ProjectLevelBuilder { @Override public void build(CompileContext context) throws ProjectBuildException { - Set affected = new HashSet(); - for (Artifact artifact : context.getProjectDescriptor().project.getArtifacts().values()) { + Set affected = new HashSet(); + for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(context.getProjectDescriptor().jpsProject)) { if (context.getScope().isAffected(artifact)) { affected.add(artifact); } } - final Set toBuild = ArtifactSorter.addIncludedArtifacts(affected, context.getProjectDescriptor().project, context.getProjectDescriptor().jpsModel); - Map artifactsMap = new HashMap(); - for (Artifact artifact : toBuild) { - artifactsMap.put(artifact.getName(), artifact); - } + final Set toBuild = ArtifactSorter.addIncludedArtifacts(affected, context.getProjectDescriptor().project, context.getProjectDescriptor().jpsModel); - final ArtifactSorter sorter = new ArtifactSorter(context.getProjectDescriptor().project, context.getProjectDescriptor().jpsModel); - final Map selfIncludingNameMap = sorter.getArtifactToSelfIncludingNameMap(); - for (String artifactName : sorter.getArtifactsSortedByInclusion()) { + final ArtifactSorter sorter = new ArtifactSorter(context.getProjectDescriptor().jpsModel); + final Map selfIncludingNameMap = sorter.getArtifactToSelfIncludingNameMap(); + for (JpsArtifact artifact : sorter.getArtifactsSortedByInclusion()) { context.checkCanceled(); - final Artifact artifact = artifactsMap.get(artifactName); - if (artifact != null) { - final String selfIncluding = selfIncludingNameMap.get(artifactName); + if (toBuild.contains(artifact)) { + final JpsArtifact selfIncluding = selfIncludingNameMap.get(artifact); if (selfIncluding != null) { - String name = selfIncluding.equals(artifact.getName()) ? "it" : "'" + selfIncluding + "' artifact"; - context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifactName + "' artifact: " + name + " includes itself in the output layout")); + String name = selfIncluding.equals(artifact) ? "it" : "'" + selfIncluding.getName() + "' artifact"; + context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifact.getName() + "' artifact: " + name + " includes itself in the output layout")); break; } if (StringUtil.isEmpty(artifact.getOutputPath())) { - context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifactName + "' artifact: output path is not specified")); + context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifact.getName() + "' artifact: output path is not specified")); break; } buildArtifact(artifact, context); @@ -68,7 +64,7 @@ public class IncArtifactBuilder extends ProjectLevelBuilder { } } - private static void buildArtifact(Artifact artifact, final CompileContext context) throws ProjectBuildException { + private static void buildArtifact(JpsArtifact artifact, final CompileContext context) throws ProjectBuildException { final ProjectDescriptor pd = context.getProjectDescriptor(); try { final ArtifactSourceFilesState state = pd.dataManager.getArtifactsBuildData().getOrCreateState(artifact, pd.project, pd.jpsModel, pd.rootsIndex); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuilderService.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuilderService.java index 2fd66a13b354..df1322c2b2ad 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuilderService.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuilderService.java @@ -1,13 +1,13 @@ package org.jetbrains.jps.incremental.artifacts.builders; -import org.jetbrains.jps.artifacts.LayoutElement; import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactCompilerInstructionCreator; import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactInstructionsBuilderContext; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; /** * @author nik */ -public abstract class LayoutElementBuilderService { +public abstract class LayoutElementBuilderService { private final Class myElementClass; protected LayoutElementBuilderService(Class elementClass) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java index ed042641aa4a..c06efc0be481 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/builders/LayoutElementBuildersRegistry.java @@ -4,11 +4,14 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ClassMap; -import org.jetbrains.jps.artifacts.*; +import org.jetbrains.jps.JpsPathUtil; import org.jetbrains.jps.idea.OwnServiceLoader; import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactCompilerInstructionCreator; import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactInstructionsBuilderContext; -import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.elements.*; +import org.jetbrains.jps.model.java.JpsProductionModuleOutputPackagingElement; +import org.jetbrains.jps.model.java.JpsTestModuleOutputPackagingElement; import java.io.File; import java.util.List; @@ -44,94 +47,90 @@ public class LayoutElementBuildersRegistry { } } - public void generateInstructions(LayoutElement layoutElement, ArtifactCompilerInstructionCreator instructionCreator, + public void generateInstructions(JpsPackagingElement layoutElement, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { final LayoutElementBuilderService builder = myBuilders.get(layoutElement.getClass()); - if (builder == null) { + if (builder != null) { + //noinspection unchecked + builder.generateInstructions(layoutElement, instructionCreator, builderContext); + } + else { LOG.error("Builder not found for artifact output layout element of class " + layoutElement.getClass()); } - builder.generateInstructions(layoutElement, instructionCreator, builderContext); } - private void generateChildrenInstructions(CompositeLayoutElement element, ArtifactCompilerInstructionCreator instructionCreator, + private void generateChildrenInstructions(JpsCompositePackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { generateInstructions(element.getChildren(), instructionCreator, builderContext); } - private void generateSubstitutionInstructions(ComplexLayoutElement element, + private void generateSubstitutionInstructions(JpsComplexPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - final List substitution = element.getSubstitution(builderContext.getProject(), builderContext.getJpsModel()); + final List substitution = element.getSubstitution(); if (substitution != null) { generateInstructions(substitution, instructionCreator, builderContext); } } - private void generateInstructions(final List elements, ArtifactCompilerInstructionCreator instructionCreator, + private void generateInstructions(final List elements, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - for (LayoutElement child : elements) { + for (JpsPackagingElement child : elements) { generateInstructions(child, instructionCreator, builderContext); } } - private static void generateModuleOutputInstructions(String moduleName, - boolean tests, - ArtifactCompilerInstructionCreator creator, - ArtifactInstructionsBuilderContext context) { - final JpsModule module = context.getRootsIndex().getModuleByName(moduleName); - if (module != null) { - final File outputDir = context.getProjectPaths().getModuleOutputDir(module, tests); - if (outputDir != null) { - creator.addDirectoryCopyInstructions(outputDir); - } + private static void generateModuleOutputInstructions(String outputUrl, ArtifactCompilerInstructionCreator creator) { + if (outputUrl != null) { + creator.addDirectoryCopyInstructions(JpsPathUtil.urlToFile(outputUrl)); } } - private class RootElementBuilder extends LayoutElementBuilderService { + private class RootElementBuilder extends LayoutElementBuilderService { public RootElementBuilder() { - super(RootElement.class); + super(JpsArtifactRootElement.class); } @Override - public void generateInstructions(RootElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { + public void generateInstructions(JpsArtifactRootElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { generateChildrenInstructions(element, instructionCreator, builderContext); } } - private class DirectoryElementBuilder extends LayoutElementBuilderService { + private class DirectoryElementBuilder extends LayoutElementBuilderService { public DirectoryElementBuilder() { - super(DirectoryElement.class); + super(JpsDirectoryPackagingElement.class); } @Override - public void generateInstructions(DirectoryElement element, + public void generateInstructions(JpsDirectoryPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - generateChildrenInstructions(element, instructionCreator.subFolder(element.getName()), builderContext); + generateChildrenInstructions(element, instructionCreator.subFolder(element.getDirectoryName()), builderContext); } } - private class ArchiveElementBuilder extends LayoutElementBuilderService { + private class ArchiveElementBuilder extends LayoutElementBuilderService { public ArchiveElementBuilder() { - super(ArchiveElement.class); + super(JpsArchivePackagingElement.class); } @Override - public void generateInstructions(ArchiveElement element, ArtifactCompilerInstructionCreator instructionCreator, + public void generateInstructions(JpsArchivePackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - generateChildrenInstructions(element, instructionCreator.archive(element.getName()), builderContext); + generateChildrenInstructions(element, instructionCreator.archive(element.getArchiveName()), builderContext); } } - private static class DirectoryCopyElementBuilder extends LayoutElementBuilderService { + private static class DirectoryCopyElementBuilder extends LayoutElementBuilderService { public DirectoryCopyElementBuilder() { - super(DirectoryCopyElement.class); + super(JpsDirectoryCopyPackagingElement.class); } @Override - public void generateInstructions(DirectoryCopyElement element, ArtifactCompilerInstructionCreator instructionCreator, + public void generateInstructions(JpsDirectoryCopyPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - final String dirPath = element.getDirPath(); + final String dirPath = element.getDirectoryPath(); if (dirPath != null) { final File directory = new File(FileUtil.toSystemDependentName(dirPath)); if (directory.isDirectory()) { @@ -141,35 +140,35 @@ public class LayoutElementBuildersRegistry { } } - private static class FileCopyElementBuilder extends LayoutElementBuilderService { + private static class FileCopyElementBuilder extends LayoutElementBuilderService { public FileCopyElementBuilder() { - super(FileCopyElement.class); + super(JpsFileCopyPackagingElement.class); } @Override - public void generateInstructions(FileCopyElement element, ArtifactCompilerInstructionCreator instructionCreator, + public void generateInstructions(JpsFileCopyPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { final String filePath = element.getFilePath(); if (filePath != null) { final File file = new File(FileUtil.toSystemDependentName(filePath)); if (file.isFile()) { - final String fileName = element.getOutputFileName(); + final String fileName = element.getRenamedOutputFileName(); instructionCreator.addFileCopyInstruction(file, fileName != null ? fileName : file.getName()); } } } } - private static class ExtractedDirectoryElementBuilder extends LayoutElementBuilderService { + private static class ExtractedDirectoryElementBuilder extends LayoutElementBuilderService { public ExtractedDirectoryElementBuilder() { - super(ExtractedDirectoryElement.class); + super(JpsExtractedDirectoryPackagingElement.class); } @Override - public void generateInstructions(ExtractedDirectoryElement element, + public void generateInstructions(JpsExtractedDirectoryPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - final String jarPath = element.getJarPath(); + final String jarPath = element.getFilePath(); final String pathInJar = element.getPathInJar(); File jarFile = new File(FileUtil.toSystemDependentName(jarPath)); if (jarFile.isFile()) { @@ -178,55 +177,55 @@ public class LayoutElementBuildersRegistry { } } - private static class ModuleOutputElementBuilder extends LayoutElementBuilderService { + private static class ModuleOutputElementBuilder extends LayoutElementBuilderService { public ModuleOutputElementBuilder() { - super(ModuleOutputElement.class); + super(JpsProductionModuleOutputPackagingElement.class); } @Override - public void generateInstructions(ModuleOutputElement element, + public void generateInstructions(JpsProductionModuleOutputPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - generateModuleOutputInstructions(element.getModuleName(), false, instructionCreator, builderContext); + generateModuleOutputInstructions(element.getOutputUrl(), instructionCreator); } } - private static class ModuleTestOutputElementBuilder extends LayoutElementBuilderService { + private static class ModuleTestOutputElementBuilder extends LayoutElementBuilderService { public ModuleTestOutputElementBuilder() { - super(ModuleTestOutputElement.class); + super(JpsTestModuleOutputPackagingElement.class); } @Override - public void generateInstructions(ModuleTestOutputElement element, + public void generateInstructions(JpsTestModuleOutputPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - generateModuleOutputInstructions(element.getModuleName(), true, instructionCreator, builderContext); + generateModuleOutputInstructions(element.getOutputUrl(), instructionCreator); } } - private class ComplexElementBuilder extends LayoutElementBuilderService { + private class ComplexElementBuilder extends LayoutElementBuilderService { public ComplexElementBuilder() { - super(ComplexLayoutElement.class); + super(JpsComplexPackagingElement.class); } @Override - public void generateInstructions(ComplexLayoutElement element, + public void generateInstructions(JpsComplexPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { generateSubstitutionInstructions(element, instructionCreator, builderContext); } } - private class ArtifactOutputElementBuilder extends LayoutElementBuilderService { + private class ArtifactOutputElementBuilder extends LayoutElementBuilderService { public ArtifactOutputElementBuilder() { - super(ArtifactLayoutElement.class); + super(JpsArtifactOutputPackagingElement.class); } @Override - public void generateInstructions(ArtifactLayoutElement element, + public void generateInstructions(JpsArtifactOutputPackagingElement element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext) { - final Artifact artifact = element.findArtifact(builderContext.getProject()); + final JpsArtifact artifact = element.getArtifactReference().resolve(); if (artifact == null) return; final String outputPath = artifact.getOutputPath(); @@ -235,10 +234,10 @@ public class LayoutElementBuildersRegistry { return; } - final LayoutElement rootElement = artifact.getRootElement(); + final JpsPackagingElement rootElement = artifact.getRootElement(); final File outputDir = new File(FileUtil.toSystemDependentName(outputPath)); - if (rootElement instanceof ArchiveElement) { - final String fileName = ((ArchiveElement)rootElement).getName(); + if (rootElement instanceof JpsArchivePackagingElement) { + final String fileName = ((JpsArchivePackagingElement)rootElement).getArchiveName(); instructionCreator.addFileCopyInstruction(new File(outputDir, fileName), fileName); } else { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/ArtifactSorter.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/ArtifactSorter.java index c77409c13760..c532a31df839 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/ArtifactSorter.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/ArtifactSorter.java @@ -17,18 +17,20 @@ package org.jetbrains.jps.incremental.artifacts.impl; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Consumer; +import com.intellij.util.Processor; import com.intellij.util.graph.CachingSemiGraph; import com.intellij.util.graph.DFSTBuilder; import com.intellij.util.graph.GraphGenerator; import gnu.trove.TIntArrayList; import gnu.trove.TIntProcedure; -import groovy.lang.Closure; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.Project; -import org.jetbrains.jps.artifacts.Artifact; -import org.jetbrains.jps.artifacts.ArtifactLayoutElement; -import org.jetbrains.jps.artifacts.ComplexLayoutElement; import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.JpsArtifactService; +import org.jetbrains.jps.model.artifact.elements.JpsArtifactOutputPackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; import java.util.*; @@ -36,55 +38,53 @@ import java.util.*; * @author nik */ public class ArtifactSorter { - private final Project myProject; private final JpsModel myModel; - private Map myArtifactToSelfIncludingName; - private List mySortedArtifacts; + private Map myArtifactToSelfIncludingName; + private List mySortedArtifacts; - public ArtifactSorter(Project project, JpsModel model) { - myProject = project; + public ArtifactSorter(JpsModel model) { myModel = model; } - public Map getArtifactToSelfIncludingNameMap() { + public Map getArtifactToSelfIncludingNameMap() { if (myArtifactToSelfIncludingName == null) { myArtifactToSelfIncludingName = computeArtifactToSelfIncludingNameMap(); } return myArtifactToSelfIncludingName; } - public List getArtifactsSortedByInclusion() { + public List getArtifactsSortedByInclusion() { if (mySortedArtifacts == null) { mySortedArtifacts = doGetSortedArtifacts(); } return mySortedArtifacts; } - private List doGetSortedArtifacts() { - GraphGenerator graph = createArtifactsGraph(); - DFSTBuilder builder = new DFSTBuilder(graph); + private List doGetSortedArtifacts() { + GraphGenerator graph = createArtifactsGraph(); + DFSTBuilder builder = new DFSTBuilder(graph); builder.buildDFST(); - List names = new ArrayList(); + List names = new ArrayList(); names.addAll(graph.getNodes()); Collections.sort(names, builder.comparator()); return names; } - private Map computeArtifactToSelfIncludingNameMap() { - final Map result = new HashMap(); - final GraphGenerator graph = createArtifactsGraph(); - for (String artifactName : graph.getNodes()) { - final Iterator in = graph.getIn(artifactName); + private Map computeArtifactToSelfIncludingNameMap() { + final Map result = new HashMap(); + final GraphGenerator graph = createArtifactsGraph(); + for (JpsArtifact artifact : graph.getNodes()) { + final Iterator in = graph.getIn(artifact); while (in.hasNext()) { - String next = in.next(); - if (next.equals(artifactName)) { - result.put(artifactName, artifactName); + JpsArtifact next = in.next(); + if (next.equals(artifact)) { + result.put(artifact, artifact); break; } } } - final DFSTBuilder builder = new DFSTBuilder(graph); + final DFSTBuilder builder = new DFSTBuilder(graph); builder.buildDFST(); if (builder.isAcyclic() && result.isEmpty()) return Collections.emptyMap(); @@ -94,8 +94,8 @@ public class ArtifactSorter { public boolean execute(int size) { if (size > 1) { for (int j = 0; j < size; j++) { - final String artifactName = builder.getNodeByTNumber(myTNumber + j); - result.put(artifactName, artifactName); + final JpsArtifact artifact = builder.getNodeByTNumber(myTNumber + j); + result.put(artifact, artifact); } } myTNumber += size; @@ -104,13 +104,13 @@ public class ArtifactSorter { }); for (int i = 0; i < graph.getNodes().size(); i++) { - final String artifactName = builder.getNodeByTNumber(i); - if (!result.containsKey(artifactName)) { - final Iterator in = graph.getIn(artifactName); + final JpsArtifact artifact = builder.getNodeByTNumber(i); + if (!result.containsKey(artifact)) { + final Iterator in = graph.getIn(artifact); while (in.hasNext()) { - final String name = result.get(in.next()); - if (name != null) { - result.put(artifactName, name); + final JpsArtifact next = result.get(in.next()); + if (next != null) { + result.put(artifact, next); } } } @@ -120,19 +120,19 @@ public class ArtifactSorter { } @NotNull - public static Set addIncludedArtifacts(@NotNull Collection artifacts, @NotNull Project project, JpsModel model) { - Set result = new HashSet(); - for (Artifact artifact : artifacts) { - collectIncludedArtifacts(artifact, project, model, new HashSet(), result, true); + public static Set addIncludedArtifacts(@NotNull Collection artifacts, @NotNull Project project, JpsModel model) { + Set result = new HashSet(); + for (JpsArtifact artifact : artifacts) { + collectIncludedArtifacts(artifact, project, model, new HashSet(), result, true); } return result; } - private static void collectIncludedArtifacts(Artifact artifact, + private static void collectIncludedArtifacts(JpsArtifact artifact, final Project project, final JpsModel model, - final Set processed, - final Set result, + final Set processed, + final Set result, final boolean withOutputPathOnly) { if (!processed.add(artifact)) { return; @@ -141,31 +141,27 @@ public class ArtifactSorter { result.add(artifact); } - processIncludedArtifacts(artifact, project, model, new Consumer() { + processIncludedArtifacts(artifact, new Consumer() { @Override - public void consume(Artifact included) { + public void consume(JpsArtifact included) { collectIncludedArtifacts(included, project, model, processed, result, withOutputPathOnly); } }); } - private GraphGenerator createArtifactsGraph() { - return GraphGenerator.create(CachingSemiGraph.create(new ArtifactsGraph(myProject, myModel))); + private GraphGenerator createArtifactsGraph() { + return GraphGenerator.create(CachingSemiGraph.create(new ArtifactsGraph(myModel.getProject()))); } - private static void processIncludedArtifacts(Artifact artifact, - final Project project, - JpsModel model, final Consumer consumer) { - artifact.getRootElement().process(project, model, new Closure(consumer) { + private static void processIncludedArtifacts(JpsArtifact artifact, final Consumer consumer) { + JpsArtifactUtil.processPackagingElements(artifact.getRootElement(), new Processor() { @Override - public Object call(Object arguments) { - if (arguments instanceof ArtifactLayoutElement) { - final Artifact includedArtifact = ((ArtifactLayoutElement)arguments).findArtifact(project); - if (includedArtifact != null) { - consumer.consume(includedArtifact); + public boolean process(JpsPackagingElement element) { + if (element instanceof JpsArtifactOutputPackagingElement) { + JpsArtifact included = ((JpsArtifactOutputPackagingElement)element).getArtifactReference().resolve(); + if (included != null) { + consumer.consume(included); } - } - if (arguments instanceof ComplexLayoutElement) { return false; } return true; @@ -173,37 +169,30 @@ public class ArtifactSorter { }); } - private static class ArtifactsGraph implements GraphGenerator.SemiGraph { - private final Set myArtifactNames; - private final Project myProject; - private final JpsModel myModel; + private static class ArtifactsGraph implements GraphGenerator.SemiGraph { + private final Set myArtifactNodes; - public ArtifactsGraph(Project project, JpsModel model) { - myProject = project; - myModel = model; - myArtifactNames = new LinkedHashSet(project.getArtifacts().keySet()); + public ArtifactsGraph(final JpsProject project) { + myArtifactNodes = new LinkedHashSet(JpsArtifactService.getInstance().getArtifacts(project)); } @Override - public Collection getNodes() { - return myArtifactNames; + public Collection getNodes() { + return myArtifactNodes; } @Override - public Iterator getIn(String name) { - final Set included = new LinkedHashSet(); - final Artifact artifact = myProject.getArtifacts().get(name); - if (artifact != null) { - final Consumer consumer = new Consumer() { - @Override - public void consume(Artifact artifact) { - if (myArtifactNames.contains(artifact.getName())) { - included.add(artifact.getName()); - } + public Iterator getIn(JpsArtifact artifact) { + final Set included = new LinkedHashSet(); + final Consumer consumer = new Consumer() { + @Override + public void consume(JpsArtifact artifact) { + if (myArtifactNodes.contains(artifact)) { + included.add(artifact); } - }; - processIncludedArtifacts(artifact, myProject, myModel, consumer); - } + } + }; + processIncludedArtifacts(artifact, consumer); return included.iterator(); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JpsArtifactUtil.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JpsArtifactUtil.java new file mode 100644 index 000000000000..c7a673e3b330 --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JpsArtifactUtil.java @@ -0,0 +1,30 @@ +package org.jetbrains.jps.incremental.artifacts.impl; + +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsComplexPackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; + +/** + * @author nik + */ +public class JpsArtifactUtil { + public static boolean processPackagingElements(@NotNull JpsPackagingElement element, @NotNull Processor processor) { + if (!processor.process(element)) { + return false; + } + + if (element instanceof JpsCompositePackagingElement) { + for (JpsPackagingElement child : ((JpsCompositePackagingElement)element).getChildren()) { + processPackagingElements(child, processor); + } + } + else if (element instanceof JpsComplexPackagingElement) { + for (JpsPackagingElement child : ((JpsComplexPackagingElement)element).getSubstitution()) { + processPackagingElements(child, processor); + } + } + return true; + } +} diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java b/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java index 307966b088b6..a4812e6b3a9a 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java +++ b/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java @@ -19,13 +19,13 @@ import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.builders.JpsBuildTestCase; import org.jetbrains.jps.cmdline.ProjectDescriptor; import org.jetbrains.jps.incremental.*; import org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLoggerImpl; import org.jetbrains.jps.incremental.java.JavaBuilderLogger; import org.jetbrains.jps.incremental.messages.BuildMessage; +import org.jetbrains.jps.model.artifact.JpsArtifact; import java.io.*; import java.util.Collections; @@ -182,7 +182,7 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase { final ProjectDescriptor projectDescriptor = createProjectDescriptor(new BuildLoggingManager(new ArtifactBuilderLoggerImpl(), javaBuilderLogger)); try { final IncProjectBuilder builder = createBuilder(projectDescriptor); - doBuild(builder, new AllProjectScope(myProject, myJpsProject, Collections.emptySet(), true), false, false, true); + doBuild(builder, new AllProjectScope(myProject, myJpsProject, Collections.emptySet(), true), false, false, true); modify(); @@ -206,7 +206,7 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase { makeBuilder.addMessageHandler(handler); - makeBuilder.build(new AllProjectScope(myProject, myJpsProject, Collections.emptySet(), false), true, false, false); + makeBuilder.build(new AllProjectScope(myProject, myJpsProject, Collections.emptySet(), false), true, false, false); final ByteArrayOutputStream makeDump = new ByteArrayOutputStream(); @@ -222,7 +222,7 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase { assertEquals(expected, actual); if (!handler.myErrors) { - createBuilder(projectDescriptor).build(new AllProjectScope(myProject, myJpsProject, Collections.emptySet(), true), false, true, false); + createBuilder(projectDescriptor).build(new AllProjectScope(myProject, myJpsProject, Collections.emptySet(), true), false, true, false); final ByteArrayOutputStream rebuildDump = new ByteArrayOutputStream(); diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy index 1097b3b86675..7311a59115c1 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy @@ -1,14 +1,16 @@ package org.jetbrains.jps.builders.rebuild + import com.intellij.openapi.application.ex.PathManagerEx import com.intellij.openapi.util.io.FileUtil import com.intellij.util.io.TestFileSystemBuilder import org.jetbrains.jps.JpsPathUtil -import org.jetbrains.jps.artifacts.Artifact import org.jetbrains.jps.builders.JpsBuildTestCase import org.jetbrains.jps.incremental.AllProjectScope import org.jetbrains.jps.incremental.BuildLoggingManager import org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLoggerImpl import org.jetbrains.jps.incremental.java.JavaBuilderLoggerImpl +import org.jetbrains.jps.model.artifact.JpsArtifact +import org.jetbrains.jps.model.artifact.JpsArtifactService import org.jetbrains.jps.model.java.JpsJavaExtensionService /** * @author nik @@ -49,7 +51,7 @@ abstract class JpsRebuildTestCase extends JpsBuildTestCase { JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myJpsProject).outputUrl = JpsPathUtil.pathToUrl(FileUtil.toSystemIndependentName(getOrCreateOutputDirectory().getAbsolutePath())) def descriptor = createProjectDescriptor(new BuildLoggingManager(new ArtifactBuilderLoggerImpl(), new JavaBuilderLoggerImpl())) try { - def scope = new AllProjectScope(myProject, myJpsProject, new HashSet(myProject.artifacts.values()), true) + def scope = new AllProjectScope(myProject, myJpsProject, new HashSet(JpsArtifactService.getInstance().getArtifacts(myJpsProject)), true) doBuild(createBuilder(descriptor), scope, false, false, true) } finally { diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderOverwriteTest.java b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderOverwriteTest.java index 3476ed99b815..69e973f9ddfc 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderOverwriteTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderOverwriteTest.java @@ -1,6 +1,6 @@ package org.jetbrains.jps.incremental.artifacts; -import org.jetbrains.jps.artifacts.Artifact; +import org.jetbrains.jps.model.artifact.JpsArtifact; import static com.intellij.util.io.TestFileSystemBuilder.fs; import static org.jetbrains.jps.incremental.artifacts.LayoutElementTestUtil.archive; @@ -13,7 +13,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase { public void testOverwriteArchives() { final String aFile = createFile("aaa.txt", "a"); final String bFile = createFile("bbb.txt", "b"); - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root() .archive("x.jar").fileCopy(aFile).end() .archive("x.jar") @@ -41,7 +41,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase { public void testOverwriteNestedArchive() { final String cFile = createFile("c.txt", "c"); final String eFile = createFile("e.txt", "e"); - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root() .archive("a.jar").archive("b.jar").fileCopy(cFile).end().end() .archive("a.jar").archive("d.jar").fileCopy(eFile)); @@ -65,7 +65,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase { public void testOverwriteFileByArchive() { final String xFile = createFile("x.txt", "1"); final String jarFile = createFile("junit.jar", "123"); - Artifact a = addArtifact(root() + JpsArtifact a = addArtifact(root() .archive("junit.jar").fileCopy(xFile).end() .fileCopy(jarFile)); buildAll(); @@ -88,7 +88,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase { public void testOverwriteArchiveByFile() { final String xFile = createFile("x.txt", "1"); final String jarFile = createFile("jdom.jar", "123"); - Artifact a = addArtifact(root() + JpsArtifact a = addArtifact(root() .fileCopy(jarFile) .archive("jdom.jar").fileCopy(xFile)); buildAll(); @@ -112,7 +112,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase { final String firstFile = createFile("d1/xxx.txt", "first"); final String secondFile = createFile("d2/xxx.txt", "second"); final String fooFile = createFile("d3/xxx.txt", "foo"); - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root().dir("ddd") .fileCopy(firstFile) .fileCopy(fooFile) @@ -144,7 +144,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase { public void testDeleteOverwritingFiles() { final String firstFile = createFile("d1/xxx.txt", "1"); final String secondFile = createFile("d2/xxx.txt", "2"); - final Artifact a = addArtifact("a", + final JpsArtifact a = addArtifact("a", root().dir("ddd").fileCopy(firstFile).fileCopy(secondFile).fileCopy(createFile("y.txt")) ); buildAll(); @@ -165,7 +165,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase { public void testUpdateManifest() { final String manifestText1 = "Manifest-Version: 1.0\r\nMain-Class: A\r\n\r\n"; final String manifest = createFile("MANIFEST.MF", manifestText1); - final Artifact a = addArtifact("a", archive("a.jar").dir("META-INF").fileCopy(manifest).fileCopy(createFile("a.txt"))); + final JpsArtifact a = addArtifact("a", archive("a.jar").dir("META-INF").fileCopy(manifest).fileCopy(createFile("a.txt"))); buildAll(); assertOutput(a, fs().archive("a.jar").dir("META-INF").file("MANIFEST.MF", manifestText1).file("a.txt")); diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderTest.java b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderTest.java index 6364fda6b6ac..5bfa32ae11c1 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderTest.java @@ -3,7 +3,7 @@ package org.jetbrains.jps.incremental.artifacts; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.PathUtil; import org.jetbrains.jps.JpsPathUtil; -import org.jetbrains.jps.artifacts.Artifact; +import org.jetbrains.jps.model.artifact.JpsArtifact; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.module.JpsModule; @@ -22,13 +22,13 @@ import static org.jetbrains.jps.incremental.artifacts.LayoutElementTestUtil.root */ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { public void testFileCopy() { - final Artifact a = addArtifact(root().fileCopy(createFile("file.txt", "foo"))); + final JpsArtifact a = addArtifact(root().fileCopy(createFile("file.txt", "foo"))); buildAll(); assertOutput(a, fs().file("file.txt", "foo")); } public void testDir() { - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root() .fileCopy(createFile("abc.txt")) .dir("dir") @@ -43,7 +43,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { } public void testArchive() { - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root() .archive("xxx.zip") .fileCopy(createFile("X.class", "data")) @@ -62,7 +62,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { public void testTwoDirsInArchive() { final String dir1 = PathUtil.getParentPath(PathUtil.getParentPath(createFile("dir1/a/x.txt"))); final String dir2 = PathUtil.getParentPath(PathUtil.getParentPath(createFile("dir2/a/y.txt"))); - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root() .archive("a.jar") .dirCopy(dir1) @@ -80,7 +80,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { } public void testArchiveInArchive() { - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root() .archive("a.jar") .archive("b.jar") @@ -95,10 +95,10 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { } public void testIncludedArtifact() { - final Artifact included = addArtifact("included", + final JpsArtifact included = addArtifact("included", root() .fileCopy(createFile("aaa.txt"))); - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root() .dir("dir") .artifact(included) @@ -117,9 +117,9 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { } public void testMergeDirectories() { - final Artifact included = addArtifact("included", + final JpsArtifact included = addArtifact("included", root().dir("dir").fileCopy(createFile("aaa.class"))); - final Artifact a = addArtifact( + final JpsArtifact a = addArtifact( root() .artifact(included) .dir("dir") @@ -134,7 +134,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { public void testCopyLibrary() { final JpsLibrary library = addProjectLibrary("lib", getJUnitJarPath()); - final Artifact a = addArtifact(root().lib(library)); + final JpsArtifact a = addArtifact(root().lib(library)); buildAll(); assertOutput(a, fs().file("junit.jar")); } @@ -142,7 +142,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { public void testModuleOutput() { final String file = createFile("src/A.java", "public class A {}"); final JpsModule module = addModule("a", PathUtil.getParentPath(file)); - final Artifact artifact = addArtifact(root().module(module)); + final JpsArtifact artifact = addArtifact(root().module(module)); buildArtifacts(artifact); assertOutput(artifact, fs().file("A.class")); @@ -151,7 +151,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { public void testIgnoredFile() { final String file = createFile("a/.svn/a.txt"); createFile("a/svn/b.txt"); - final Artifact a = addArtifact(root().dirCopy(PathUtil.getParentPath(PathUtil.getParentPath(file)))); + final JpsArtifact a = addArtifact(root().dirCopy(PathUtil.getParentPath(PathUtil.getParentPath(file)))); buildAll(); assertOutput(a, fs().dir("svn").file("b.txt")); } @@ -159,7 +159,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { public void testIgnoredFileInArchive() { final String file = createFile("a/.svn/a.txt"); createFile("a/svn/b.txt"); - final Artifact a = addArtifact(archive("a.jar").dirCopy(PathUtil.getParentPath(PathUtil.getParentPath(file)))); + final JpsArtifact a = addArtifact(archive("a.jar").dirCopy(PathUtil.getParentPath(PathUtil.getParentPath(file)))); buildAll(); assertOutput(a, fs().archive("a.jar").dir("svn").file("b.txt")); } @@ -175,7 +175,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { module.getContentRootsList().addUrl(JpsPathUtil.pathToUrl(dir)); module.getExcludeRootsList().addUrl(JpsPathUtil.pathToUrl(excluded)); - final Artifact a = addArtifact(root().dirCopy(excluded)); + final JpsArtifact a = addArtifact(root().dirCopy(excluded)); buildAll(); assertOutput(a, fs().file("a.txt")); } @@ -191,13 +191,13 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { module.getContentRootsList().addUrl(JpsPathUtil.pathToUrl(dir)); module.getExcludeRootsList().addUrl(JpsPathUtil.pathToUrl(PathUtil.getParentPath(file))); - final Artifact a = addArtifact(root().dirCopy(dir)); + final JpsArtifact a = addArtifact(root().dirCopy(dir)); buildAll(); assertOutput(a, fs().file("b.txt")); } public void testExtractDirectory() { - final Artifact a = addArtifact("a", root().dir("dir").extractedDir(getJUnitJarPath(), "/junit/textui/")); + final JpsArtifact a = addArtifact("a", root().dir("dir").extractedDir(getJUnitJarPath(), "/junit/textui/")); buildAll(); assertOutput(a, fs().dir("dir") .file("ResultPrinter.class") @@ -205,7 +205,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { } public void testPackExtractedDirectory() { - final Artifact a = addArtifact("a", root().archive("a.jar").extractedDir(getJUnitJarPath(), "/junit/textui/")); + final JpsArtifact a = addArtifact("a", root().archive("a.jar").extractedDir(getJUnitJarPath(), "/junit/textui/")); buildAll(); assertOutput(a, fs().archive("a.jar") .file("ResultPrinter.class") @@ -213,14 +213,14 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { } public void testSelfIncludingArtifact() { - final Artifact a = addArtifact("a", root()); + final JpsArtifact a = addArtifact("a", root()); LayoutElementTestUtil.addArtifactToLayout(a, a); assertBuildFailed(a); } public void testCircularInclusion() { - final Artifact a = addArtifact("a", root()); - final Artifact b = addArtifact("b", root()); + final JpsArtifact a = addArtifact("a", root()); + final JpsArtifact b = addArtifact("b", root()); LayoutElementTestUtil.addArtifactToLayout(a, b); LayoutElementTestUtil.addArtifactToLayout(b, a); assertBuildFailed(a); @@ -228,10 +228,10 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { } public void testArtifactContainingSelfIncludingArtifact() { - Artifact c = addArtifact("c", root()); - final Artifact a = addArtifact("a", root().artifact(c)); + JpsArtifact c = addArtifact("c", root()); + final JpsArtifact a = addArtifact("a", root().artifact(c)); LayoutElementTestUtil.addArtifactToLayout(a, a); - final Artifact b = addArtifact("b", root().artifact(a)); + final JpsArtifact b = addArtifact("b", root().artifact(a)); buildArtifacts(c); assertBuildFailed(b); @@ -243,7 +243,7 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase { final String firstFile = createFile("src/A.txt"); final String manifestFile = createFile("src/MANIFEST.MF"); final String lastFile = createFile("src/Z.txt"); - final Artifact a = addArtifact(archive("a.jar").dir("META-INF") + final JpsArtifact a = addArtifact(archive("a.jar").dir("META-INF") .fileCopy(firstFile).fileCopy(manifestFile).fileCopy(lastFile)); buildArtifacts(a); final String jarPath = a.getOutputPath() + "/a.jar"; diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderTestCase.java b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderTestCase.java index bb56fcaba8bf..4128284bfae2 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderTestCase.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/ArtifactBuilderTestCase.java @@ -21,7 +21,6 @@ import com.intellij.util.io.TestFileSystemBuilder; import com.intellij.util.text.UniqueNameGenerator; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.JpsPathUtil; -import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.builders.JpsBuildTestCase; import org.jetbrains.jps.cmdline.ProjectDescriptor; import org.jetbrains.jps.incremental.AllProjectScope; @@ -29,6 +28,9 @@ import org.jetbrains.jps.incremental.BuildLoggingManager; import org.jetbrains.jps.incremental.CompileScope; import org.jetbrains.jps.incremental.IncProjectBuilder; import org.jetbrains.jps.incremental.java.JavaBuilderLoggerImpl; +import org.jetbrains.jps.model.artifact.DirectoryArtifactType; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.JpsArtifactService; import org.jetbrains.jps.model.java.*; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsOrderRootType; @@ -58,8 +60,11 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase { @Override protected void tearDown() throws Exception { - for (Artifact artifact : myProject.getArtifacts().values()) { - FileUtil.delete(new File(FileUtil.toSystemDependentName(artifact.getOutputPath()))); + for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(myJpsProject)) { + String outputPath = artifact.getOutputPath(); + if (outputPath != null) { + FileUtil.delete(new File(FileUtil.toSystemDependentName(outputPath))); + } } myDescriptor.release(); myProjectDir = null; @@ -81,11 +86,20 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase { } } - protected Artifact addArtifact(LayoutElementTestUtil.LayoutElementCreator root) { - final String name = UniqueNameGenerator.generateUniqueName("a", myProject.getArtifacts().keySet()); + protected JpsArtifact addArtifact(LayoutElementTestUtil.LayoutElementCreator root) { + Set usedNames = getArtifactNames(); + final String name = UniqueNameGenerator.generateUniqueName("a", usedNames); return addArtifact(name, root); } - + + private Set getArtifactNames() { + Set usedNames = new HashSet(); + for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(myJpsProject)) { + usedNames.add(artifact.getName()); + } + return usedNames; + } + private File getOrCreateProjectDir() { if (myProjectDir == null) { try { @@ -98,14 +112,10 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase { return myProjectDir; } - protected Artifact addArtifact(String name, LayoutElementTestUtil.LayoutElementCreator root) { - assertFalse("Artifact " + name + " already exists", myProject.getArtifacts().containsKey(name)); - Artifact artifact = new Artifact(); - artifact.setName(name); - artifact.setRootElement(root.buildElement()); - + protected JpsArtifact addArtifact(String name, LayoutElementTestUtil.LayoutElementCreator root) { + assertFalse("JpsArtifact " + name + " already exists", getArtifactNames().contains(name)); + JpsArtifact artifact = JpsArtifactService.getInstance().addArtifact(myJpsProject, name, root.buildElement(), DirectoryArtifactType.INSTANCE); artifact.setOutputPath(getAbsolutePath("out/artifacts/" + name)); - myProject.getArtifacts().put(name, artifact); return artifact; } @@ -138,15 +148,15 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase { } protected void buildAll() { - Collection artifacts = myProject.getArtifacts().values(); - buildArtifacts(artifacts.toArray(new Artifact[artifacts.size()])); + Collection artifacts = JpsArtifactService.getInstance().getArtifacts(myJpsProject); + buildArtifacts(artifacts.toArray(new JpsArtifact[artifacts.size()])); } - protected void buildArtifacts(Artifact... artifact) { + protected void buildArtifacts(JpsArtifact... artifact) { doBuild(false, false, artifact); } - private void doBuild(boolean force, final boolean shouldFail, Artifact... artifacts) { + private void doBuild(boolean force, final boolean shouldFail, JpsArtifact... artifacts) { if (myDescriptor == null) { myDescriptor = createProjectDescriptor(new BuildLoggingManager(myArtifactBuilderLogger, new JavaBuilderLoggerImpl())); myDescriptor.incUsageCounter(); @@ -154,7 +164,7 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase { myArtifactBuilderLogger.clear(); IncProjectBuilder builder = createBuilder(myDescriptor); final CompileScope scope = new AllProjectScope(myDescriptor.project, myDescriptor.jpsProject, - new HashSet(Arrays.asList(artifacts)), force); + new HashSet(Arrays.asList(artifacts)), force); doBuild(builder, scope, shouldFail, !force, false); } @@ -164,11 +174,11 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase { return FileUtil.toSystemIndependentName(file.getAbsolutePath()); } - protected static void assertEmptyOutput(Artifact a1) { + protected static void assertEmptyOutput(JpsArtifact a1) { assertOutput(a1, fs()); } - protected void assertBuildFailed(Artifact a) { + protected void assertBuildFailed(JpsArtifact a) { doBuild(false, true, a); } @@ -208,7 +218,7 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase { assertSameElements(myArtifactBuilderLogger.myCopiedFilePaths, copiedPaths); } - protected static void assertOutput(Artifact a, TestFileSystemBuilder expected) { + protected static void assertOutput(JpsArtifact a, TestFileSystemBuilder expected) { expected.build().assertDirectoryEqual(new File(FileUtil.toSystemDependentName(a.getOutputPath()))); } diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/IncrementalArtifactBuildingTest.java b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/IncrementalArtifactBuildingTest.java index 3b2af9f18b8a..b59c2603c9b4 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/IncrementalArtifactBuildingTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/IncrementalArtifactBuildingTest.java @@ -16,7 +16,7 @@ package org.jetbrains.jps.incremental.artifacts; import com.intellij.util.PathUtil; -import org.jetbrains.jps.artifacts.Artifact; +import org.jetbrains.jps.model.artifact.JpsArtifact; import static com.intellij.util.io.TestFileSystemItem.fs; import static org.jetbrains.jps.incremental.artifacts.LayoutElementTestUtil.archive; @@ -29,7 +29,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { public void testCopyChangedFile() { String file1 = createFile("a.txt", "aaa"); String file2 = createFile("b.txt", "bbb"); - final Artifact a = addArtifact(root().fileCopy(file1).fileCopy(file2)); + final JpsArtifact a = addArtifact(root().fileCopy(file1).fileCopy(file2)); buildAll(); assertOutput(a, fs().file("a.txt", "aaa").file("b.txt", "bbb")); @@ -45,7 +45,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { public void testRemoveDeletedFile() { String file1 = createFile("a.txt"); String file2 = createFile("b.txt"); - final Artifact a = addArtifact("a", root().fileCopy(file1).fileCopy(file2)); + final JpsArtifact a = addArtifact("a", root().fileCopy(file1).fileCopy(file2)); buildAll(); assertOutput(a, fs().file("a.txt").file("b.txt")); @@ -59,7 +59,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { public void testPackChangedFile() { String file1 = createFile("a.txt", "aaa"); String file2 = createFile("b.txt", "bbb"); - final Artifact a = addArtifact(archive("a.jar").fileCopy(file1).fileCopy(file2)); + final JpsArtifact a = addArtifact(archive("a.jar").fileCopy(file1).fileCopy(file2)); buildAll(); assertOutput(a, fs().archive("a.jar").file("a.txt", "aaa").file("b.txt", "bbb")); buildAllAndAssertUpToDate(); @@ -74,7 +74,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { public void testRemoveDeletedFileFromArchive() { String file1 = createFile("a.txt"); String file2 = createFile("b.txt"); - final Artifact a = addArtifact("a", archive("a.jar").fileCopy(file1).fileCopy(file2)); + final JpsArtifact a = addArtifact("a", archive("a.jar").fileCopy(file1).fileCopy(file2)); buildAll(); assertOutput(a, fs().archive("a.jar").file("a.txt").file("b.txt")); @@ -87,8 +87,8 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { public void testOneFileInTwoArtifacts() { final String file = createFile("file.txt"); - final Artifact a1 = addArtifact("a1", root().dir("dir").fileCopy(file)); - final Artifact a2 = addArtifact("a2", root().dir("dir2").fileCopy(file)); + final JpsArtifact a1 = addArtifact("a1", root().dir("dir").fileCopy(file)); + final JpsArtifact a2 = addArtifact("a2", root().dir("dir2").fileCopy(file)); buildAll(); buildArtifacts(a1); assertUpToDate(); @@ -120,7 +120,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { public void testRenameFile() throws Exception { final String file = createFile("a/a.txt"); - final Artifact a = addArtifact(root().dirCopy(PathUtil.getParentPath(file))); + final JpsArtifact a = addArtifact(root().dirCopy(PathUtil.getParentPath(file))); buildAll(); assertOutput(a, fs().file("a.txt")); @@ -132,7 +132,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { //IDEADEV-25840 public void testUpdateFileIfCaseOfLetterInNameChanged() throws Exception { final String file = createFile("a/a.txt"); - final Artifact a = addArtifact("a", root().dirCopy(PathUtil.getParentPath(file))); + final JpsArtifact a = addArtifact("a", root().dirCopy(PathUtil.getParentPath(file))); buildAll(); assertOutput(a, fs().file("a.txt")); @@ -144,8 +144,8 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { //IDEADEV-41556 public void testDeleteFilesFromSelectedArtifactsOnly() throws Exception { final String file = createFile("a/a.txt"); - final Artifact a1 = addArtifact("a1", root().dirCopy(PathUtil.getParentPath(file))); - final Artifact a2 = addArtifact("a2", root().dirCopy(PathUtil.getParentPath(file))); + final JpsArtifact a1 = addArtifact("a1", root().dirCopy(PathUtil.getParentPath(file))); + final JpsArtifact a2 = addArtifact("a2", root().dirCopy(PathUtil.getParentPath(file))); buildAll(); assertOutput(a1, fs().file("a.txt")); @@ -165,8 +165,8 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { public void testTwoArtifactsWithSameOutput() throws Exception { final String res1 = PathUtil.getParentPath(createFile("res1/a.txt", "1")); final String res2 = PathUtil.getParentPath(createFile("res2/a.txt", "2")); - final Artifact a1 = addArtifact("a1", root().dirCopy(res1)); - final Artifact a2 = addArtifact("a2", root().dirCopy(res2)); + final JpsArtifact a1 = addArtifact("a1", root().dirCopy(res1)); + final JpsArtifact a2 = addArtifact("a2", root().dirCopy(res2)); a2.setOutputPath(a1.getOutputPath()); assertEquals(a1.getOutputPath(), a2.getOutputPath()); diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/LayoutElementTestUtil.java b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/LayoutElementTestUtil.java index e8159c432807..a2db2b5bec5b 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/LayoutElementTestUtil.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/LayoutElementTestUtil.java @@ -16,48 +16,48 @@ package org.jetbrains.jps.incremental.artifacts; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.artifacts.*; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.elements.*; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.module.JpsModule; -import java.util.Collections; - /** * @author nik */ public class LayoutElementTestUtil { public static LayoutElementCreator root() { - return new LayoutElementCreator(new RootElement(Collections.emptyList()), null); + return new LayoutElementCreator(JpsPackagingElementFactory.getInstance().createArtifactRoot(), null); } public static LayoutElementCreator archive(String name) { - return new LayoutElementCreator(new ArchiveElement(name, Collections.emptyList()), null); + return new LayoutElementCreator(JpsPackagingElementFactory.getInstance().createArchive(name), null); } - public static void addArtifactToLayout(Artifact main, Artifact included) { - final ArtifactLayoutElement element = new ArtifactLayoutElement(); - element.setArtifactName(included.getName()); - ((CompositeLayoutElement)main.getRootElement()).getChildren().add(element); + public static void addArtifactToLayout(JpsArtifact main, JpsArtifact included) { + main.getRootElement().addChild(JpsPackagingElementFactory.getInstance().createArtifactOutput(included.createReference())); } public static class LayoutElementCreator { - private CompositeLayoutElement myElement; + private JpsPackagingElementFactory myFactory; + private JpsCompositePackagingElement myElement; private LayoutElementCreator myParent; - public LayoutElementCreator(CompositeLayoutElement element, LayoutElementCreator parent) { + public LayoutElementCreator(JpsCompositePackagingElement element, LayoutElementCreator parent) { myElement = element; myParent = parent; + myFactory = JpsPackagingElementFactory.getInstance(); } public LayoutElementCreator dir(String name) { - DirectoryElement dir = new DirectoryElement(name, Collections.emptyList()); - myElement.getChildren().add(dir); + JpsDirectoryPackagingElement dir = myFactory.createDirectory(name); + myElement.addChild(dir); return new LayoutElementCreator(dir, this); } public LayoutElementCreator archive(String name) { - ArchiveElement archive = new ArchiveElement(name, Collections.emptyList()); - myElement.getChildren().add(archive); + JpsArchivePackagingElement archive = myFactory.createArchive(name); + myElement.addChild(archive); return new LayoutElementCreator(archive, this); } @@ -66,49 +66,39 @@ public class LayoutElementTestUtil { } public LayoutElementCreator fileCopy(String filePath, @Nullable String outputFileName) { - return element(new FileCopyElement(filePath, outputFileName)); + return element(myFactory.createFileCopy(filePath, outputFileName)); } public LayoutElementCreator dirCopy(String dirPath) { - return element(new DirectoryCopyElement(dirPath)); + return element(myFactory.createDirectoryCopy(dirPath)); } public LayoutElementCreator module(JpsModule module) { - final ModuleOutputElement element = new ModuleOutputElement(); - element.setModuleName(module.getName()); - return element(element); + return element(JpsJavaExtensionService.getInstance().createProductionModuleOutput(module.createReference())); } - public LayoutElementCreator element(LayoutElement element) { - myElement.getChildren().add(element); + public LayoutElementCreator element(JpsPackagingElement element) { + myElement.addChild(element); return this; } public LayoutElementCreator lib(JpsLibrary library) { - final LibraryFilesElement element = new LibraryFilesElement(); - element.setLibraryName(library.getName()); - element.setLibraryLevel(LibraryFilesElement.PROJECT_LEVEL); - return element(element); + return element(myFactory.createLibraryElement(library.createReference())); } public LayoutElementCreator extractedDir(String jarPath, String pathInJar) { - ExtractedDirectoryElement dir = new ExtractedDirectoryElement(); - dir.setJarPath(jarPath); - dir.setPathInJar(pathInJar); - return element(dir); + return element(myFactory.createExtractedDirectory(jarPath, pathInJar)); } - public LayoutElementCreator artifact(Artifact included) { - final ArtifactLayoutElement element = new ArtifactLayoutElement(); - element.setArtifactName(included.getName()); - return element(element); + public LayoutElementCreator artifact(JpsArtifact included) { + return element(myFactory.createArtifactOutput(included.createReference())); } public LayoutElementCreator end() { return myParent; } - public CompositeLayoutElement buildElement() { + public JpsCompositePackagingElement buildElement() { if (myParent != null) { return myParent.buildElement(); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java new file mode 100644 index 000000000000..0a606c3490d5 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/DirectoryArtifactType.java @@ -0,0 +1,8 @@ +package org.jetbrains.jps.model.artifact; + +/** + * @author nik + */ +public class DirectoryArtifactType extends JpsArtifactType { + public static final DirectoryArtifactType INSTANCE = new DirectoryArtifactType(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java new file mode 100644 index 000000000000..75552f36bf71 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JarArtifactType.java @@ -0,0 +1,8 @@ +package org.jetbrains.jps.model.artifact; + +/** + * @author nik + */ +public class JarArtifactType extends JpsArtifactType { + public static final JarArtifactType INSTANCE = new JarArtifactType(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifact.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifact.java new file mode 100644 index 000000000000..0fbf491a99d3 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifact.java @@ -0,0 +1,30 @@ +package org.jetbrains.jps.model.artifact; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsNamedElement; +import org.jetbrains.jps.model.JpsReferenceableElement; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; + +/** + * @author nik + */ +public interface JpsArtifact extends JpsNamedElement, JpsReferenceableElement, JpsCompositeElement { + @NotNull + JpsArtifactType getArtifactType(); + + @Nullable + String getOutputPath(); + + void setOutputPath(@Nullable String outputPath); + + @NotNull + JpsCompositePackagingElement getRootElement(); + + void setRootElement(@NotNull JpsCompositePackagingElement rootElement); + + @NotNull + @Override + JpsArtifactReference createReference(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactReference.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactReference.java new file mode 100644 index 000000000000..27ed4a107b36 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactReference.java @@ -0,0 +1,16 @@ +package org.jetbrains.jps.model.artifact; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.JpsModel; + +/** + * @author nik + */ +public interface JpsArtifactReference extends JpsElementReference { + @NotNull + String getArtifactName(); + + @Override + JpsArtifactReference asExternal(@NotNull JpsModel model); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactService.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactService.java new file mode 100644 index 000000000000..46fd347ed472 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactService.java @@ -0,0 +1,27 @@ +package org.jetbrains.jps.model.artifact; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; +import org.jetbrains.jps.service.JpsServiceManager; + +import java.util.List; + +/** + * @author nik + */ +public abstract class JpsArtifactService { + + public static JpsArtifactService getInstance() { + return JpsServiceManager.getInstance().getService(JpsArtifactService.class); + } + + public abstract List getArtifacts(@NotNull JpsProject project); + + public abstract JpsArtifact addArtifact(@NotNull JpsProject project, + @NotNull String name, + @NotNull JpsCompositePackagingElement rootElement, + @NotNull JpsArtifactType type); + + public abstract JpsArtifactReference createReference(@NotNull String artifactName); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java new file mode 100644 index 000000000000..811e1c0156b5 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/JpsArtifactType.java @@ -0,0 +1,14 @@ +package org.jetbrains.jps.model.artifact; + +import org.jetbrains.jps.model.DummyJpsElementProperties; +import org.jetbrains.jps.model.JpsElementType; + +/** + * @author nik + */ +public abstract class JpsArtifactType extends JpsElementType { + @Override + public DummyJpsElementProperties createCopy(DummyJpsElementProperties properties) { + return DummyJpsElementProperties.INSTANCE; + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArchivePackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArchivePackagingElement.java new file mode 100644 index 000000000000..8b7395602db5 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArchivePackagingElement.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.artifact.elements; + +/** + * @author nik + */ +public interface JpsArchivePackagingElement extends JpsCompositePackagingElement { + String getArchiveName(); + + void setArchiveName(String directoryName); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArtifactOutputPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArtifactOutputPackagingElement.java new file mode 100644 index 000000000000..cd9441f81839 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArtifactOutputPackagingElement.java @@ -0,0 +1,12 @@ +package org.jetbrains.jps.model.artifact.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.JpsArtifactReference; + +/** + * @author nik + */ +public interface JpsArtifactOutputPackagingElement extends JpsComplexPackagingElement { + @NotNull + JpsArtifactReference getArtifactReference(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArtifactRootElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArtifactRootElement.java new file mode 100644 index 000000000000..3a189d26d480 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsArtifactRootElement.java @@ -0,0 +1,7 @@ +package org.jetbrains.jps.model.artifact.elements; + +/** + * @author nik + */ +public interface JpsArtifactRootElement extends JpsCompositePackagingElement { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsComplexPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsComplexPackagingElement.java new file mode 100644 index 000000000000..5fa1b3ff5b3c --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsComplexPackagingElement.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.artifact.elements; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsComplexPackagingElement extends JpsPackagingElement { + List getSubstitution(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsCompositePackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsCompositePackagingElement.java new file mode 100644 index 000000000000..32f5cf37657a --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsCompositePackagingElement.java @@ -0,0 +1,15 @@ +package org.jetbrains.jps.model.artifact.elements; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsCompositePackagingElement extends JpsPackagingElement { + @NotNull + List getChildren(); + + E addChild(@NotNull E child); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsDirectoryCopyPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsDirectoryCopyPackagingElement.java new file mode 100644 index 000000000000..718379984123 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsDirectoryCopyPackagingElement.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.artifact.elements; + +/** + * @author nik + */ +public interface JpsDirectoryCopyPackagingElement extends JpsPackagingElement { + String getDirectoryPath(); + + void setDirectoryPath(String path); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsDirectoryPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsDirectoryPackagingElement.java new file mode 100644 index 000000000000..3f4e0b832fd2 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsDirectoryPackagingElement.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model.artifact.elements; + +/** + * @author nik + */ +public interface JpsDirectoryPackagingElement extends JpsCompositePackagingElement { + + String getDirectoryName(); + + void setDirectoryName(String directoryName); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsExtractedDirectoryPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsExtractedDirectoryPackagingElement.java new file mode 100644 index 000000000000..51ddb695717b --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsExtractedDirectoryPackagingElement.java @@ -0,0 +1,14 @@ +package org.jetbrains.jps.model.artifact.elements; + +/** + * @author nik + */ +public interface JpsExtractedDirectoryPackagingElement extends JpsPackagingElement { + String getFilePath(); + + void setFilePath(String path); + + String getPathInJar(); + + void setPathInJar(String pathInJar); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsFileCopyPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsFileCopyPackagingElement.java new file mode 100644 index 000000000000..d1ca3199c882 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsFileCopyPackagingElement.java @@ -0,0 +1,15 @@ +package org.jetbrains.jps.model.artifact.elements; + +/** + * @author nik + */ +public interface JpsFileCopyPackagingElement extends JpsPackagingElement { + + String getFilePath(); + + void setFilePath(String filePath); + + String getRenamedOutputFileName(); + + void setRenamedOutputFileName(String renamedOutputFileName); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsLibraryFilesPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsLibraryFilesPackagingElement.java new file mode 100644 index 000000000000..3916f43d74fb --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsLibraryFilesPackagingElement.java @@ -0,0 +1,12 @@ +package org.jetbrains.jps.model.artifact.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.library.JpsLibraryReference; + +/** + * @author nik + */ +public interface JpsLibraryFilesPackagingElement extends JpsPackagingElement { + @NotNull + JpsLibraryReference getLibraryReference(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsModuleOutputPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsModuleOutputPackagingElement.java new file mode 100644 index 000000000000..645a3a8b76aa --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsModuleOutputPackagingElement.java @@ -0,0 +1,16 @@ +package org.jetbrains.jps.model.artifact.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsModuleReference; + +/** + * @author nik + */ +public interface JpsModuleOutputPackagingElement extends JpsPackagingElement { + @NotNull + JpsModuleReference getModuleReference(); + + @Nullable + String getOutputUrl(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsPackagingElement.java new file mode 100644 index 000000000000..961fde54783f --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsPackagingElement.java @@ -0,0 +1,9 @@ +package org.jetbrains.jps.model.artifact.elements; + +import org.jetbrains.jps.model.JpsElement; + +/** + * @author nik + */ +public interface JpsPackagingElement extends JpsElement { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsPackagingElementFactory.java b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsPackagingElementFactory.java new file mode 100644 index 000000000000..9ea13f9adfbd --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/artifact/elements/JpsPackagingElementFactory.java @@ -0,0 +1,43 @@ +package org.jetbrains.jps.model.artifact.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.artifact.JpsArtifactReference; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.service.JpsServiceManager; + +/** + * @author nik + */ +public abstract class JpsPackagingElementFactory { + public static JpsPackagingElementFactory getInstance() { + return JpsServiceManager.getInstance().getService(JpsPackagingElementFactory.class); + } + + @NotNull + public abstract JpsDirectoryCopyPackagingElement createDirectoryCopy(@NotNull String directoryPath); + + public abstract JpsPackagingElement createParentDirectories(String path, JpsPackagingElement element); + + @NotNull + public abstract JpsFileCopyPackagingElement createFileCopy(@NotNull String filePath, @Nullable String outputFileName); + + @NotNull + public abstract JpsExtractedDirectoryPackagingElement createExtractedDirectory(@NotNull String jarPath, @NotNull String pathInJar); + + @NotNull + public abstract JpsDirectoryPackagingElement createDirectory(@NotNull String directoryName); + + @NotNull + public abstract JpsArchivePackagingElement createArchive(@NotNull String archiveName); + + @NotNull + public abstract JpsArtifactRootElement createArtifactRoot(); + + @NotNull + public abstract JpsLibraryFilesPackagingElement createLibraryElement(@NotNull JpsLibraryReference reference); + + @NotNull + public abstract JpsArtifactOutputPackagingElement createArtifactOutput(@NotNull JpsArtifactReference reference); + +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java index 1f040a4050cf..32d2bb317fe4 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java @@ -6,6 +6,7 @@ import org.jetbrains.jps.model.JpsElementKind; import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleReference; import org.jetbrains.jps.service.JpsServiceManager; import java.util.List; @@ -14,6 +15,12 @@ import java.util.List; * @author nik */ public abstract class JpsJavaExtensionService { + @NotNull + public abstract JpsProductionModuleOutputPackagingElement createProductionModuleOutput(@NotNull JpsModuleReference moduleReference); + + @NotNull + public abstract JpsTestModuleOutputPackagingElement createTestModuleOutput(@NotNull JpsModuleReference moduleReference); + public static JpsJavaExtensionService getInstance() { return JpsServiceManager.getInstance().getService(JpsJavaExtensionService.class); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsProductionModuleOutputPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsProductionModuleOutputPackagingElement.java new file mode 100644 index 000000000000..8dcb5e7b9df1 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsProductionModuleOutputPackagingElement.java @@ -0,0 +1,9 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.artifact.elements.JpsModuleOutputPackagingElement; + +/** + * @author nik + */ +public interface JpsProductionModuleOutputPackagingElement extends JpsModuleOutputPackagingElement { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsTestModuleOutputPackagingElement.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsTestModuleOutputPackagingElement.java new file mode 100644 index 000000000000..54fd07929fac --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsTestModuleOutputPackagingElement.java @@ -0,0 +1,9 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.artifact.elements.JpsModuleOutputPackagingElement; + +/** + * @author nik + */ +public interface JpsTestModuleOutputPackagingElement extends JpsModuleOutputPackagingElement { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java index 77d4c35772e7..6fea6b3f42c9 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java @@ -5,6 +5,7 @@ import org.jetbrains.jps.model.JpsElementProperties; import org.jetbrains.jps.model.JpsNamedElement; import org.jetbrains.jps.model.JpsReferenceableElement; +import java.io.File; import java.util.List; /** @@ -31,4 +32,6 @@ public interface JpsLibrary extends JpsNamedElement, JpsReferenceableElement getFiles(final JpsOrderRootType rootType); } diff --git a/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.artifact.JpsArtifactService b/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.artifact.JpsArtifactService new file mode 100644 index 000000000000..0313eb7ef3a3 --- /dev/null +++ b/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.artifact.JpsArtifactService @@ -0,0 +1 @@ +org.jetbrains.jps.model.artifact.impl.JpsArtifactServiceImpl \ No newline at end of file diff --git a/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.artifact.elements.JpsPackagingElementFactory b/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.artifact.elements.JpsPackagingElementFactory new file mode 100644 index 000000000000..bbc28002f730 --- /dev/null +++ b/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.artifact.elements.JpsPackagingElementFactory @@ -0,0 +1 @@ +org.jetbrains.jps.model.artifact.impl.elements.JpsPackagingElementFactoryImpl \ No newline at end of file diff --git a/jps/model/src/org/jetbrains/jps/JpsPathUtil.java b/jps/model-impl/src/org/jetbrains/jps/JpsPathUtil.java similarity index 95% rename from jps/model/src/org/jetbrains/jps/JpsPathUtil.java rename to jps/model-impl/src/org/jetbrains/jps/JpsPathUtil.java index 6c111f0a7d6e..39b45108f72d 100644 --- a/jps/model/src/org/jetbrains/jps/JpsPathUtil.java +++ b/jps/model-impl/src/org/jetbrains/jps/JpsPathUtil.java @@ -1,6 +1,7 @@ package org.jetbrains.jps; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; @@ -59,7 +60,7 @@ public class JpsPathUtil { } public static File urlToFile(String url) { - return new File(FileUtil.toSystemDependentName(urlToPath(url))); + return new File(FileUtilRt.toSystemDependentName(urlToPath(url))); } public static String urlToPath(String url) { diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactImpl.java new file mode 100644 index 000000000000..ff86c36ae079 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactImpl.java @@ -0,0 +1,74 @@ +package org.jetbrains.jps.model.artifact.impl; + +import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.DummyJpsElementProperties; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.JpsArtifactType; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; +import org.jetbrains.jps.model.impl.JpsElementKindBase; +import org.jetbrains.jps.model.impl.JpsNamedCompositeElementBase; +import org.jetbrains.jps.model.impl.JpsTypedDataImpl; +import org.jetbrains.jps.model.impl.JpsTypedDataKind; + +/** + * @author nik + */ +public class JpsArtifactImpl extends JpsNamedCompositeElementBase implements JpsArtifact { + private static final JpsElementKind ROOT_ELEMENT_KIND = new JpsElementKindBase("root element"); + private static final JpsTypedDataKind TYPED_DATA_KIND = new JpsTypedDataKind(); + private String myOutputPath; + + public JpsArtifactImpl(@NotNull String name, @NotNull JpsCompositePackagingElement rootElement, @NotNull JpsArtifactType type) { + super(name); + myContainer.setChild(ROOT_ELEMENT_KIND, rootElement); + myContainer.setChild(TYPED_DATA_KIND, new JpsTypedDataImpl(type, DummyJpsElementProperties.INSTANCE)); + } + + private JpsArtifactImpl(JpsArtifactImpl original) { + super(original); + myOutputPath = original.myOutputPath; + } + + @NotNull + @Override + public JpsArtifactImpl createCopy() { + return new JpsArtifactImpl(this); + } + + public String getOutputPath() { + return myOutputPath; + } + + public void setOutputPath(@Nullable String outputPath) { + if (!Comparing.equal(myOutputPath, outputPath)) { + myOutputPath = outputPath; + fireElementChanged(); + } + } + + @NotNull + @Override + public JpsArtifactType getArtifactType() { + return myContainer.getChild(TYPED_DATA_KIND).getType(); + } + + @NotNull + @Override + public JpsArtifactReferenceImpl createReference() { + return new JpsArtifactReferenceImpl(getName()); + } + + @NotNull + @Override + public JpsCompositePackagingElement getRootElement() { + return myContainer.getChild(ROOT_ELEMENT_KIND); + } + + @Override + public void setRootElement(@NotNull JpsCompositePackagingElement rootElement) { + myContainer.setChild(ROOT_ELEMENT_KIND, rootElement); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactKind.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactKind.java new file mode 100644 index 000000000000..4a26f23bcfe2 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactKind.java @@ -0,0 +1,17 @@ +package org.jetbrains.jps.model.artifact.impl; + +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.impl.JpsElementCollectionKind; +import org.jetbrains.jps.model.impl.JpsElementKindBase; + +/** +* @author nik +*/ +public class JpsArtifactKind extends JpsElementKindBase { + public static final JpsArtifactKind INSTANCE = new JpsArtifactKind(); + public static final JpsElementCollectionKind ARTIFACT_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); + + public JpsArtifactKind() { + super("artifact"); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactReferenceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactReferenceImpl.java new file mode 100644 index 000000000000..e792f0bdea76 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactReferenceImpl.java @@ -0,0 +1,39 @@ +package org.jetbrains.jps.model.artifact.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementFactory; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.JpsArtifactReference; +import org.jetbrains.jps.model.impl.JpsNamedElementReferenceBase; + +/** + * @author nik + */ +public class JpsArtifactReferenceImpl extends JpsNamedElementReferenceBase implements JpsArtifactReference { + public JpsArtifactReferenceImpl(@NotNull String artifactName) { + super(JpsArtifactKind.ARTIFACT_COLLECTION_KIND, artifactName, JpsElementFactory.getInstance().createProjectReference()); + } + + private JpsArtifactReferenceImpl(JpsArtifactReferenceImpl original) { + super(original); + } + + @NotNull + @Override + public JpsArtifactReferenceImpl createCopy() { + return new JpsArtifactReferenceImpl(this); + } + + @NotNull + @Override + public String getArtifactName() { + return myElementName; + } + + @Override + public JpsArtifactReferenceImpl asExternal(@NotNull JpsModel model) { + model.registerExternalReference(this); + return this; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactServiceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactServiceImpl.java new file mode 100644 index 000000000000..257280671159 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/JpsArtifactServiceImpl.java @@ -0,0 +1,36 @@ +package org.jetbrains.jps.model.artifact.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.JpsArtifactReference; +import org.jetbrains.jps.model.artifact.JpsArtifactService; +import org.jetbrains.jps.model.artifact.JpsArtifactType; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; +import org.jetbrains.jps.model.impl.JpsElementCollectionImpl; + +import java.util.Collections; +import java.util.List; + +/** + * @author nik + */ +public class JpsArtifactServiceImpl extends JpsArtifactService { + @Override + public List getArtifacts(@NotNull JpsProject project) { + JpsElementCollectionImpl collection = project.getContainer().getChild(JpsArtifactKind.ARTIFACT_COLLECTION_KIND); + return collection != null ? collection.getElements() : Collections.emptyList(); + } + + @Override + public JpsArtifact addArtifact(@NotNull JpsProject project, @NotNull String name, @NotNull JpsCompositePackagingElement rootElement, + @NotNull JpsArtifactType type) { + JpsArtifact artifact = new JpsArtifactImpl(name, rootElement, type); + return project.getContainer().getOrSetChild(JpsArtifactKind.ARTIFACT_COLLECTION_KIND).addChild(artifact); + } + + @Override + public JpsArtifactReference createReference(@NotNull String artifactName) { + return new JpsArtifactReferenceImpl(artifactName); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArchivePackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArchivePackagingElementImpl.java new file mode 100644 index 000000000000..a5ecd991224c --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArchivePackagingElementImpl.java @@ -0,0 +1,40 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsArchivePackagingElement; + +/** + * @author nik + */ +public class JpsArchivePackagingElementImpl extends JpsCompositePackagingElementBase + implements JpsArchivePackagingElement { + private String myArchiveName; + + public JpsArchivePackagingElementImpl(String archiveName) { + myArchiveName = archiveName; + } + + private JpsArchivePackagingElementImpl(JpsArchivePackagingElementImpl original) { + super(original); + myArchiveName = original.myArchiveName; + } + + @NotNull + @Override + public JpsArchivePackagingElementImpl createCopy() { + return new JpsArchivePackagingElementImpl(this); + } + + @Override + public String getArchiveName() { + return myArchiveName; + } + + @Override + public void setArchiveName(String directoryName) { + if (!myArchiveName.equals(directoryName)) { + myArchiveName = directoryName; + fireElementChanged(); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArtifactOutputPackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArtifactOutputPackagingElementImpl.java new file mode 100644 index 000000000000..1e6b6be891d6 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArtifactOutputPackagingElementImpl.java @@ -0,0 +1,56 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.artifact.JpsArtifact; +import org.jetbrains.jps.model.artifact.JpsArtifactReference; +import org.jetbrains.jps.model.artifact.elements.JpsArtifactOutputPackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsArtifactRootElement; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; +import org.jetbrains.jps.model.impl.JpsElementKindBase; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author nik + */ +public class JpsArtifactOutputPackagingElementImpl extends JpsComplexPackagingElementBase + implements JpsArtifactOutputPackagingElement { + private static final JpsElementKind ARTIFACT_REFERENCE_KIND = new JpsElementKindBase("artifact reference"); + + public JpsArtifactOutputPackagingElementImpl(@NotNull JpsArtifactReference reference) { + myContainer.setChild(ARTIFACT_REFERENCE_KIND, reference); + } + + private JpsArtifactOutputPackagingElementImpl(JpsArtifactOutputPackagingElementImpl original) { + super(original); + } + + @NotNull + @Override + public JpsArtifactOutputPackagingElementImpl createCopy() { + return new JpsArtifactOutputPackagingElementImpl(this); + } + + @Override + @NotNull + public JpsArtifactReference getArtifactReference() { + return myContainer.getChild(ARTIFACT_REFERENCE_KIND); + } + + @Override + public List getSubstitution() { + JpsArtifact artifact = getArtifactReference().resolve(); + if (artifact == null) return Collections.emptyList(); + JpsCompositePackagingElement rootElement = artifact.getRootElement(); + if (rootElement instanceof JpsArtifactRootElement) { + return new ArrayList(rootElement.getChildren()); + } + else { + return Collections.singletonList(rootElement); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArtifactRootElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArtifactRootElementImpl.java new file mode 100644 index 000000000000..940a5d4967aa --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsArtifactRootElementImpl.java @@ -0,0 +1,22 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsArtifactRootElement; + +/** + * @author nik + */ +public class JpsArtifactRootElementImpl extends JpsCompositePackagingElementBase implements JpsArtifactRootElement { + public JpsArtifactRootElementImpl() { + } + + private JpsArtifactRootElementImpl(JpsArtifactRootElementImpl original) { + super(original); + } + + @NotNull + @Override + public JpsArtifactRootElementImpl createCopy() { + return new JpsArtifactRootElementImpl(); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsComplexPackagingElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsComplexPackagingElementBase.java new file mode 100644 index 000000000000..c1274c42ea27 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsComplexPackagingElementBase.java @@ -0,0 +1,17 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import org.jetbrains.jps.model.artifact.elements.JpsComplexPackagingElement; +import org.jetbrains.jps.model.impl.JpsCompositeElementBase; + +/** + * @author nik + */ +public abstract class JpsComplexPackagingElementBase> extends JpsCompositeElementBase implements + JpsComplexPackagingElement { + protected JpsComplexPackagingElementBase() { + } + + protected JpsComplexPackagingElementBase(JpsComplexPackagingElementBase original) { + super(original); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsCompositePackagingElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsCompositePackagingElementBase.java new file mode 100644 index 000000000000..3b0ca80b33c0 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsCompositePackagingElementBase.java @@ -0,0 +1,38 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; +import org.jetbrains.jps.model.impl.JpsCompositeElementBase; +import org.jetbrains.jps.model.impl.JpsElementCollectionKind; +import org.jetbrains.jps.model.impl.JpsElementKindBase; + +import java.util.List; + +/** + * @author nik + */ +public abstract class JpsCompositePackagingElementBase> extends JpsCompositeElementBase + implements JpsCompositePackagingElement { + private static final JpsElementCollectionKind CHILDREN_KIND = new JpsElementCollectionKind(new JpsElementKindBase("child")); + + protected JpsCompositePackagingElementBase() { + myContainer.setChild(CHILDREN_KIND); + } + + protected JpsCompositePackagingElementBase(JpsCompositePackagingElementBase original) { + super(original); + } + + @NotNull + @Override + public List getChildren() { + return myContainer.getChild(CHILDREN_KIND).getElements(); + } + + + @Override + public E addChild(@NotNull E child) { + return myContainer.getChild(CHILDREN_KIND).addChild(child); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsDirectoryCopyPackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsDirectoryCopyPackagingElementImpl.java new file mode 100644 index 000000000000..81dcb44edb3a --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsDirectoryCopyPackagingElementImpl.java @@ -0,0 +1,30 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsDirectoryCopyPackagingElement; + +/** + * @author nik + */ +public class JpsDirectoryCopyPackagingElementImpl extends JpsFileCopyPackagingElementBase + implements JpsDirectoryCopyPackagingElement { + public JpsDirectoryCopyPackagingElementImpl(String directoryPath) { + super(directoryPath); + } + + @NotNull + @Override + public JpsDirectoryCopyPackagingElementImpl createCopy() { + return new JpsDirectoryCopyPackagingElementImpl(myFilePath); + } + + @Override + public String getDirectoryPath() { + return getFilePath(); + } + + @Override + public void setDirectoryPath(String path) { + setFilePath(path); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsDirectoryPackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsDirectoryPackagingElementImpl.java new file mode 100644 index 000000000000..04ffa3b5544d --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsDirectoryPackagingElementImpl.java @@ -0,0 +1,39 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsDirectoryPackagingElement; + +/** + * @author nik + */ +public class JpsDirectoryPackagingElementImpl extends JpsCompositePackagingElementBase implements JpsDirectoryPackagingElement { + private String myDirectoryName; + + public JpsDirectoryPackagingElementImpl(String directoryName) { + myDirectoryName = directoryName; + } + + private JpsDirectoryPackagingElementImpl(JpsDirectoryPackagingElementImpl original) { + super(original); + myDirectoryName = original.myDirectoryName; + } + + @NotNull + @Override + public JpsDirectoryPackagingElementImpl createCopy() { + return new JpsDirectoryPackagingElementImpl(this); + } + + @Override + public String getDirectoryName() { + return myDirectoryName; + } + + @Override + public void setDirectoryName(String directoryName) { + if (!myDirectoryName.equals(directoryName)) { + myDirectoryName = directoryName; + fireElementChanged(); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsExtractedDirectoryPackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsExtractedDirectoryPackagingElementImpl.java new file mode 100644 index 000000000000..ff3f4ca9bc7a --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsExtractedDirectoryPackagingElementImpl.java @@ -0,0 +1,43 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsExtractedDirectoryPackagingElement; + +/** + * @author nik + */ +public class JpsExtractedDirectoryPackagingElementImpl extends JpsFileCopyPackagingElementBase + implements JpsExtractedDirectoryPackagingElement { + private String myPathInJar; + + public JpsExtractedDirectoryPackagingElementImpl(String filePath, String pathInJar) { + super(filePath); + myPathInJar = pathInJar; + } + + @NotNull + @Override + public JpsExtractedDirectoryPackagingElementImpl createCopy() { + return new JpsExtractedDirectoryPackagingElementImpl(myFilePath, myPathInJar); + } + + @Override + public void applyChanges(@NotNull JpsExtractedDirectoryPackagingElementImpl modified) { + super.applyChanges(modified); + setPathInJar(modified.myPathInJar); + } + + @Override + public String getPathInJar() { + return myPathInJar; + } + + @Override + public void setPathInJar(String pathInJar) { + if (!Comparing.equal(myPathInJar, pathInJar)) { + myPathInJar = pathInJar; + fireElementChanged(); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsFileCopyPackagingElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsFileCopyPackagingElementBase.java new file mode 100644 index 000000000000..e81ba2ce656b --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsFileCopyPackagingElementBase.java @@ -0,0 +1,34 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; +import org.jetbrains.jps.model.impl.JpsElementBase; + +/** + * @author nik + */ +public abstract class JpsFileCopyPackagingElementBase> extends JpsElementBase implements + JpsPackagingElement { + protected String myFilePath; + + public JpsFileCopyPackagingElementBase(String filePath) { + myFilePath = filePath; + } + + @Override + public void applyChanges(@NotNull Self modified) { + setFilePath(modified.myFilePath); + } + + public String getFilePath() { + return myFilePath; + } + + public void setFilePath(String filePath) { + if (!Comparing.equal(myFilePath, filePath)) { + myFilePath = filePath; + fireElementChanged(); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsFileCopyPackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsFileCopyPackagingElementImpl.java new file mode 100644 index 000000000000..4b188a1ecb94 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsFileCopyPackagingElementImpl.java @@ -0,0 +1,42 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.elements.JpsFileCopyPackagingElement; + +/** + * @author nik + */ +public class JpsFileCopyPackagingElementImpl extends JpsFileCopyPackagingElementBase implements JpsFileCopyPackagingElement { + private String myRenamedOutputFileName; + + public JpsFileCopyPackagingElementImpl(String filePath, String renamedOutputFileName) { + super(filePath); + myRenamedOutputFileName = renamedOutputFileName; + } + + @NotNull + @Override + public JpsFileCopyPackagingElementImpl createCopy() { + return new JpsFileCopyPackagingElementImpl(myFilePath, myRenamedOutputFileName); + } + + @Override + public void applyChanges(@NotNull JpsFileCopyPackagingElementImpl modified) { + super.applyChanges(modified); + setRenamedOutputFileName(modified.myRenamedOutputFileName); + } + + @Override + public String getRenamedOutputFileName() { + return myRenamedOutputFileName; + } + + @Override + public void setRenamedOutputFileName(String renamedOutputFileName) { + if (!Comparing.equal(myRenamedOutputFileName, renamedOutputFileName)) { + myRenamedOutputFileName = renamedOutputFileName; + fireElementChanged(); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsLibraryFilesPackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsLibraryFilesPackagingElementImpl.java new file mode 100644 index 000000000000..3900ae7874a7 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsLibraryFilesPackagingElementImpl.java @@ -0,0 +1,61 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.artifact.elements.JpsLibraryFilesPackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElementFactory; +import org.jetbrains.jps.model.impl.JpsElementKindBase; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsOrderRootType; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author nik + */ +public class JpsLibraryFilesPackagingElementImpl extends JpsComplexPackagingElementBase implements JpsLibraryFilesPackagingElement { + private static final JpsElementKind LIBRARY_REFERENCE_KIND = new JpsElementKindBase("library reference"); + + public JpsLibraryFilesPackagingElementImpl(@NotNull JpsLibraryReference reference) { + myContainer.setChild(LIBRARY_REFERENCE_KIND, reference); + } + + private JpsLibraryFilesPackagingElementImpl(JpsLibraryFilesPackagingElementImpl original) { + super(original); + } + + @NotNull + @Override + public JpsLibraryFilesPackagingElementImpl createCopy() { + return new JpsLibraryFilesPackagingElementImpl(this); + } + + @Override + @NotNull + public JpsLibraryReference getLibraryReference() { + return myContainer.getChild(LIBRARY_REFERENCE_KIND); + } + + @Override + public List getSubstitution() { + JpsLibrary library = getLibraryReference().resolve(); + if (library == null) return Collections.emptyList(); + List result = new ArrayList(); + for (File file : library.getFiles(JpsOrderRootType.COMPILED)) { + String path = FileUtil.toSystemIndependentName(file.getAbsolutePath()); + if (file.isDirectory()) { + result.add(JpsPackagingElementFactory.getInstance().createDirectoryCopy(path)); + } + else { + result.add(JpsPackagingElementFactory.getInstance().createFileCopy(path, null)); + } + } + return result; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsModuleOutputPackagingElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsModuleOutputPackagingElementBase.java new file mode 100644 index 000000000000..8e4a1c27523b --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsModuleOutputPackagingElementBase.java @@ -0,0 +1,43 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.artifact.elements.JpsModuleOutputPackagingElement; +import org.jetbrains.jps.model.impl.JpsCompositeElementBase; +import org.jetbrains.jps.model.impl.JpsElementKindBase; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleReference; + +/** + * @author nik + */ +public abstract class JpsModuleOutputPackagingElementBase> extends JpsCompositeElementBase implements + JpsModuleOutputPackagingElement { + private static final JpsElementKind MODULE_REFERENCE_KIND = new JpsElementKindBase("module reference"); + + public JpsModuleOutputPackagingElementBase(JpsModuleReference moduleReference) { + myContainer.setChild(MODULE_REFERENCE_KIND, moduleReference); + } + + public JpsModuleOutputPackagingElementBase(JpsModuleOutputPackagingElementBase original) { + super(original); + } + + @Override + @NotNull + public JpsModuleReference getModuleReference() { + return myContainer.getChild(MODULE_REFERENCE_KIND); + } + + @Override + @Nullable + public String getOutputUrl() { + JpsModule module = getModuleReference().resolve(); + if (module == null) return null; + return getOutputUrl(module); + } + + @Nullable + protected abstract String getOutputUrl(@NotNull JpsModule module); +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsPackagingElementFactoryImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsPackagingElementFactoryImpl.java new file mode 100644 index 000000000000..62c0de6379cc --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/artifact/impl/elements/JpsPackagingElementFactoryImpl.java @@ -0,0 +1,95 @@ +package org.jetbrains.jps.model.artifact.impl.elements; + +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.artifact.JpsArtifactReference; +import org.jetbrains.jps.model.artifact.elements.*; +import org.jetbrains.jps.model.library.JpsLibraryReference; + +/** + * @author nik + */ +public class JpsPackagingElementFactoryImpl extends JpsPackagingElementFactory { + + @Override + @NotNull + public JpsDirectoryCopyPackagingElement createDirectoryCopy(@NotNull String directoryPath) { + return new JpsDirectoryCopyPackagingElementImpl(directoryPath); + } + + @Override + public JpsPackagingElement createParentDirectories(String relativeOutputPath, JpsPackagingElement element) { + relativeOutputPath = StringUtil.trimStart(relativeOutputPath, "/"); + if (relativeOutputPath.length() == 0) { + return element; + } + int slash = relativeOutputPath.indexOf('/'); + if (slash == -1) slash = relativeOutputPath.length(); + String rootName = relativeOutputPath.substring(0, slash); + String pathTail = relativeOutputPath.substring(slash); + final JpsDirectoryPackagingElement root = createDirectory(rootName); + final JpsCompositePackagingElement last = getOrCreateDirectoryOrArchive(root, pathTail, true); + last.addChild(element); + return root; + } + + @NotNull + private JpsCompositePackagingElement getOrCreateDirectoryOrArchive(@NotNull JpsCompositePackagingElement root, + @NotNull @NonNls String path, final boolean directory) { + path = StringUtil.trimStart(StringUtil.trimEnd(path, "/"), "/"); + if (path.length() == 0) { + return root; + } + int index = path.lastIndexOf('/'); + String lastName = path.substring(index + 1); + String parentPath = index != -1 ? path.substring(0, index) : ""; + + final JpsCompositePackagingElement parent = getOrCreateDirectoryOrArchive(root, parentPath, true); + final JpsCompositePackagingElement last = directory ? createDirectory(lastName) : createArchive(lastName); + return parent.addChild(last); + } + + @Override + @NotNull + public JpsFileCopyPackagingElement createFileCopy(@NotNull String filePath, @Nullable String outputFileName) { + return new JpsFileCopyPackagingElementImpl(filePath, outputFileName); + } + + @Override + @NotNull + public JpsExtractedDirectoryPackagingElement createExtractedDirectory(@NotNull String jarPath, @NotNull String pathInJar) { + return new JpsExtractedDirectoryPackagingElementImpl(jarPath, pathInJar); + } + + @Override + @NotNull + public JpsDirectoryPackagingElement createDirectory(@NotNull String directoryName) { + return new JpsDirectoryPackagingElementImpl(directoryName); + } + + @Override + @NotNull + public JpsArchivePackagingElement createArchive(@NotNull String archiveName) { + return new JpsArchivePackagingElementImpl(archiveName); + } + + @Override + @NotNull + public JpsArtifactRootElement createArtifactRoot() { + return new JpsArtifactRootElementImpl(); + } + + @Override + @NotNull + public JpsLibraryFilesPackagingElement createLibraryElement(@NotNull JpsLibraryReference reference) { + return new JpsLibraryFilesPackagingElementImpl(reference); + } + + @Override + @NotNull + public JpsArtifactOutputPackagingElement createArtifactOutput(@NotNull JpsArtifactReference reference) { + return new JpsArtifactOutputPackagingElementImpl(reference); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java index db46e70af118..d1b084eaa6b0 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java @@ -8,6 +8,7 @@ import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.java.*; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleReference; import org.jetbrains.jps.model.module.JpsModuleSourceRoot; import java.util.ArrayList; @@ -123,4 +124,16 @@ public class JpsJavaExtensionServiceImpl extends JpsJavaExtensionService { } return null; } + + @Override + @NotNull + public JpsProductionModuleOutputPackagingElement createProductionModuleOutput(@NotNull JpsModuleReference moduleReference) { + return new JpsProductionModuleOutputPackagingElementImpl(moduleReference); + } + + @Override + @NotNull + public JpsTestModuleOutputPackagingElement createTestModuleOutput(@NotNull JpsModuleReference moduleReference) { + return new JpsTestModuleOutputPackagingElementImpl(moduleReference); + } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsProductionModuleOutputPackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsProductionModuleOutputPackagingElementImpl.java new file mode 100644 index 000000000000..57b700ce88a8 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsProductionModuleOutputPackagingElementImpl.java @@ -0,0 +1,33 @@ +package org.jetbrains.jps.model.java.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.impl.elements.JpsModuleOutputPackagingElementBase; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; +import org.jetbrains.jps.model.java.JpsProductionModuleOutputPackagingElement; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleReference; + +/** + * @author nik + */ +public class JpsProductionModuleOutputPackagingElementImpl extends JpsModuleOutputPackagingElementBase + implements JpsProductionModuleOutputPackagingElement { + public JpsProductionModuleOutputPackagingElementImpl(JpsModuleReference moduleReference) { + super(moduleReference); + } + + private JpsProductionModuleOutputPackagingElementImpl(JpsProductionModuleOutputPackagingElementImpl original) { + super(original); + } + + @NotNull + @Override + public JpsProductionModuleOutputPackagingElementImpl createCopy() { + return new JpsProductionModuleOutputPackagingElementImpl(this); + } + + @Override + protected String getOutputUrl(@NotNull JpsModule module) { + return JpsJavaExtensionService.getInstance().getOutputUrl(module, false); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsTestModuleOutputPackagingElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsTestModuleOutputPackagingElementImpl.java new file mode 100644 index 000000000000..2199ab934210 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsTestModuleOutputPackagingElementImpl.java @@ -0,0 +1,33 @@ +package org.jetbrains.jps.model.java.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.artifact.impl.elements.JpsModuleOutputPackagingElementBase; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; +import org.jetbrains.jps.model.java.JpsTestModuleOutputPackagingElement; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleReference; + +/** + * @author nik + */ +public class JpsTestModuleOutputPackagingElementImpl extends JpsModuleOutputPackagingElementBase + implements JpsTestModuleOutputPackagingElement { + public JpsTestModuleOutputPackagingElementImpl(JpsModuleReference moduleReference) { + super(moduleReference); + } + + private JpsTestModuleOutputPackagingElementImpl(JpsTestModuleOutputPackagingElementImpl original) { + super(original); + } + + @NotNull + @Override + public JpsTestModuleOutputPackagingElementImpl createCopy() { + return new JpsTestModuleOutputPackagingElementImpl(this); + } + + @Override + protected String getOutputUrl(@NotNull JpsModule module) { + return JpsJavaExtensionService.getInstance().getOutputUrl(module, true); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java index fb5b9b14ec20..1c100c760ce7 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java @@ -1,10 +1,15 @@ package org.jetbrains.jps.model.library.impl; +import com.intellij.openapi.util.io.FileUtilRt; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.JpsPathUtil; import org.jetbrains.jps.model.*; import org.jetbrains.jps.model.impl.*; import org.jetbrains.jps.model.library.*; +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -94,4 +99,41 @@ public class JpsLibraryImpl

extends JpsNamedComp ((JpsReferenceableElement)getParent().getParent()).createReference(); return new JpsLibraryReferenceImpl(getName(), parentReference); } + + @Override + public List getFiles(final JpsOrderRootType rootType) { + List files = new ArrayList(); + for (JpsLibraryRoot root : getRoots(rootType)) { + final File file = JpsPathUtil.urlToFile(root.getUrl()); + switch (root.getInclusionOptions()) { + case ROOT_ITSELF: + files.add(file); + break; + case ARCHIVES_UNDER_ROOT: + collectArchives(file, false, files); + break; + case ARCHIVES_UNDER_ROOT_RECURSIVELY: + collectArchives(file, true, files); + break; + } + } + return files; + } + + private static void collectArchives(File file, boolean recursively, Collection result) { + final File[] children = file.listFiles(); + if (children != null) { + for (File child : children) { + final String extension = FileUtilRt.getExtension(child.getName()); + if (child.isDirectory()) { + if (recursively) { + collectArchives(child, recursively, result); + } + } + else if (extension.equals("jar") || extension.equals("zip")) { + result.add(child); + } + } + } + } } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java index 72cf3483a712..f1a634917e45 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java @@ -6,9 +6,11 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsCompositeElement; import org.jetbrains.jps.model.JpsElementReference; import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.JpsArtifactType; import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.serialization.artifact.JpsPackagingElementLoader; import org.jetbrains.jps.model.serialization.facet.JpsModuleExtensionLoader; import java.util.Collections; @@ -57,8 +59,17 @@ public abstract class JpsModelLoaderExtension { return Collections.emptyList(); } + public List> getPackagingElementLoaders() { + return Collections.emptyList(); + } + @Nullable public JpsOrderRootType getSdkRootType(@NotNull String typeId) { return null; } + + @Nullable + public JpsArtifactType getArtifactType(@NotNull String typeId) { + return null; + } } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleLoader.java index a7f5289ac162..aae1daef722d 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleLoader.java @@ -93,7 +93,7 @@ public class JpsModuleLoader { } } - private static JpsElementReference createLibraryTableReference(String level) { + public static JpsElementReference createLibraryTableReference(String level) { JpsElementFactory elementFactory = JpsElementFactory.getInstance(); if (level.equals("project")) { return elementFactory.createProjectReference(); diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java index fac9f2ab232d..59ac7a38c855 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.model.serialization; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.ArrayUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,10 +13,12 @@ import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.java.JpsJavaModuleType; import org.jetbrains.jps.model.library.JpsSdkType; import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.serialization.artifact.JpsArtifactLoader; import org.jetbrains.jps.model.serialization.facet.JpsFacetLoader; import org.jetbrains.jps.service.JpsServiceManager; import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -68,14 +71,23 @@ public class JpsProjectLoader extends JpsLoaderBase { private void loadFromDirectory(File dir) { JpsSdkType projectSdkType = loadProjectRoot(loadRootElement(new File(dir, "misc.xml"))); loadModules(loadRootElement(new File(dir, "modules.xml")), projectSdkType); - final File[] libraryFiles = new File(dir, "libraries").listFiles(); - if (libraryFiles != null) { - for (File libraryFile : libraryFiles) { - if (isXmlFile(libraryFile)) { - loadProjectLibraries(loadRootElement(libraryFile)); - } - } + for (File libraryFile : listXmlFiles(new File(dir, "libraries"))) { + loadProjectLibraries(loadRootElement(libraryFile)); } + for (File artifactFile : listXmlFiles(new File(dir, "artifacts"))) { + loadArtifacts(loadRootElement(artifactFile)); + } + } + + @NotNull + private static File[] listXmlFiles(final File dir) { + File[] files = dir.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + return isXmlFile(file); + } + }); + return files != null ? files : ArrayUtil.EMPTY_FILE_ARRAY; } private void loadFromIpr(File iprFile) { @@ -83,6 +95,11 @@ public class JpsProjectLoader extends JpsLoaderBase { JpsSdkType projectSdkType = loadProjectRoot(root); loadModules(root, projectSdkType); loadProjectLibraries(findComponent(root, "libraryTable")); + loadArtifacts(findComponent(root, "ArtifactManager")); + } + + private void loadArtifacts(Element artifactManagerComponent) { + JpsArtifactLoader.loadArtifacts(myProject, artifactManagerComponent); } @Nullable diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerState.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactManagerState.java similarity index 95% rename from java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerState.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactManagerState.java index 92b26d1e22ab..d6591845e838 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerState.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactManagerState.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.packaging.impl.artifacts; +package org.jetbrains.jps.model.serialization.artifact; import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.Property; diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPropertiesState.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactPropertiesState.java similarity index 95% rename from java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPropertiesState.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactPropertiesState.java index 597997f52486..7dca3c58f751 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPropertiesState.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactPropertiesState.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.packaging.impl.artifacts; +package org.jetbrains.jps.model.serialization.artifact; import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.util.xmlb.annotations.Tag; diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactState.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactState.java similarity index 95% rename from java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactState.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactState.java index f9e58053b330..2d7c02a5f385 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactState.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactState.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.packaging.impl.artifacts; +package org.jetbrains.jps.model.serialization.artifact; import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.util.xmlb.annotations.Tag; @@ -33,7 +33,7 @@ public class ArtifactState { @NonNls public static final String NAME_ATTRIBUTE = "name"; private String myName; private String myOutputPath; - private String myArtifactType = PlainArtifactType.ID; + private String myArtifactType; private boolean myBuildOnMake; private Element myRootElement; private List myPropertiesList = new ArrayList(); diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsArtifactLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsArtifactLoader.java new file mode 100644 index 000000000000..15534c5fcf35 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsArtifactLoader.java @@ -0,0 +1,136 @@ +package org.jetbrains.jps.model.serialization.artifact; + +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.xmlb.XmlSerializer; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsElementFactory; +import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.artifact.*; +import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElementFactory; +import org.jetbrains.jps.model.serialization.JpsModelLoaderExtension; +import org.jetbrains.jps.model.serialization.JpsModuleLoader; +import org.jetbrains.jps.service.JpsServiceManager; + +import java.util.Arrays; +import java.util.List; + +/** + * @author nik + */ +public class JpsArtifactLoader { + private static List> STANDARD_LOADERS = Arrays.asList(); + + public static void loadArtifacts(@NotNull JpsProject project, @Nullable Element componentElement) { + JpsArtifactService service = JpsArtifactService.getInstance(); + for (Element artifactElement : JDOMUtil.getChildren(componentElement, "artifact")) { + ArtifactState state = XmlSerializer.deserialize(artifactElement, ArtifactState.class); + if (state == null) continue; + JpsArtifactType artifactType = getArtifactType(state.getArtifactType()); + JpsPackagingElement rootElement = loadPackagingElement(state.getRootElement()); + if (rootElement != null) { + JpsArtifact artifact = service.addArtifact(project, state.getName(), (JpsCompositePackagingElement)rootElement, artifactType); + artifact.setOutputPath(state.getOutputPath()); + } + } + } + + @Nullable + private static JpsPackagingElement loadPackagingElement(Element element) { + JpsPackagingElement packagingElement = createPackagingElement(element); + if (packagingElement instanceof JpsCompositePackagingElement) { + for (Element childElement : JDOMUtil.getChildren(element, "element")) { + JpsPackagingElement child = loadPackagingElement(childElement); + if (child != null) { + ((JpsCompositePackagingElement)packagingElement).addChild(child); + } + } + } + return packagingElement; + } + + @Nullable + private static JpsPackagingElement createPackagingElement(Element element) { + String typeId = element.getAttributeValue("id"); + JpsPackagingElementFactory factory = JpsPackagingElementFactory.getInstance(); + if (typeId.equals("root")) { + return factory.createArtifactRoot(); + } + if (typeId.equals("directory")) { + return factory.createDirectory(element.getAttributeValue("name")); + } + if (typeId.equals("archive")) { + return factory.createArchive(element.getAttributeValue("name")); + } + if (typeId.equals("file-copy")) { + return factory.createFileCopy(element.getAttributeValue("path"), + element.getAttributeValue("output-file-name")); + } + if (typeId.equals("dir-copy")) { + return factory.createDirectoryCopy(element.getAttributeValue("path")); + } + if (typeId.equals("extracted-dir")) { + return factory.createExtractedDirectory(element.getAttributeValue("path"), + element.getAttributeValue("path-in-jar")); + } + if (typeId.equals("library")) { + String level = element.getAttributeValue("level"); + String libraryName = element.getAttributeValue("name"); + String moduleName = element.getAttributeValue("module-name"); + JpsElementReference parentReference; + if (moduleName != null) { + parentReference = JpsElementFactory.getInstance().createModuleReference(moduleName); + } + else { + parentReference = JpsModuleLoader.createLibraryTableReference(level); + } + return factory.createLibraryElement(JpsElementFactory.getInstance().createLibraryReference(libraryName, parentReference)); + } + if (typeId.equals("artifact")) { + return factory.createArtifactOutput(JpsArtifactService.getInstance().createReference(element.getAttributeValue("artifact-name"))); + } + JpsPackagingElementLoader loader = findElementLoader(typeId); + if (loader != null) { + return loader.load(element); + } + return null; + } + + private static JpsArtifactType getArtifactType(@Nullable String typeId) { + if (typeId == null || "plain".equals(typeId)) { + return DirectoryArtifactType.INSTANCE; + } + if (typeId.equals("jar")) { + return JarArtifactType.INSTANCE; + } + for (JpsModelLoaderExtension extension : JpsServiceManager.getInstance().getExtensions(JpsModelLoaderExtension.class)) { + JpsArtifactType type = extension.getArtifactType(typeId); + if (type != null) { + return type; + } + } + return DirectoryArtifactType.INSTANCE; + } + + @Nullable + private static JpsPackagingElementLoader findElementLoader(@NotNull String typeId) { + for (JpsPackagingElementLoader loader : STANDARD_LOADERS) { + if (loader.getTypeId().equals(typeId)) { + return loader; + } + } + for (JpsModelLoaderExtension extension : JpsServiceManager.getInstance().getExtensions(JpsModelLoaderExtension.class)) { + for (JpsPackagingElementLoader loader : extension.getPackagingElementLoaders()) { + if (loader.getTypeId().equals(typeId)) { + return loader; + } + } + } + return null; + } +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsPackagingElementLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsPackagingElementLoader.java new file mode 100644 index 000000000000..3aca2b9751ab --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsPackagingElementLoader.java @@ -0,0 +1,21 @@ +package org.jetbrains.jps.model.serialization.artifact; + +import org.jdom.Element; +import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; + +/** + * @author nik + */ +public abstract class JpsPackagingElementLoader { + private final String myTypeId; + + protected JpsPackagingElementLoader(String typeId) { + myTypeId = typeId; + } + + public String getTypeId() { + return myTypeId; + } + + public abstract E load(Element element); +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelLoaderExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelLoaderExtension.java index 23b449144c66..794e853097a9 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelLoaderExtension.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelLoaderExtension.java @@ -3,6 +3,7 @@ package org.jetbrains.jps.model.serialization.java; import com.intellij.openapi.util.JDOMUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementFactory; import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.JpsUrlList; import org.jetbrains.jps.model.java.*; @@ -10,6 +11,10 @@ import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.serialization.JpsModelLoaderExtension; +import org.jetbrains.jps.model.serialization.artifact.JpsPackagingElementLoader; + +import java.util.Arrays; +import java.util.List; /** * @author nik @@ -74,6 +79,11 @@ public class JpsJavaModelLoaderExtension extends JpsModelLoaderExtension { return null; } + @Override + public List> getPackagingElementLoaders() { + return Arrays.asList(new JpsModuleOutputPackagingElementLoader(), new JpsTestModuleOutputPackagingElementLoader()); + } + private static void loadExplodedDirectoryExtension(JpsModule module, Element rootModelComponent) { final Element exploded = rootModelComponent.getChild("exploded"); if (exploded != null) { @@ -112,4 +122,27 @@ public class JpsJavaModelLoaderExtension extends JpsModelLoaderExtension { result.addUrl(root.getAttributeValue("url")); } } + + private static class JpsModuleOutputPackagingElementLoader extends JpsPackagingElementLoader { + private JpsModuleOutputPackagingElementLoader() { + super("module-output"); + } + + @Override + public JpsProductionModuleOutputPackagingElement load(Element element) { + return JpsJavaExtensionService.getInstance().createProductionModuleOutput(JpsElementFactory.getInstance().createModuleReference(element.getAttributeValue("name"))); + } + } + + private static class JpsTestModuleOutputPackagingElementLoader extends JpsPackagingElementLoader { + private JpsTestModuleOutputPackagingElementLoader() { + super("module-test-output"); + } + + @Override + public JpsTestModuleOutputPackagingElement load(Element element) { + return JpsJavaExtensionService.getInstance().createTestModuleOutput( + JpsElementFactory.getInstance().createModuleReference(element.getAttributeValue("name"))); + } + } } diff --git a/jps/model/jps-model.iml b/jps/model/jps-model.iml index 64cff6c7c701..3571c5219fe6 100644 --- a/jps/model/jps-model.iml +++ b/jps/model/jps-model.iml @@ -11,6 +11,7 @@ + diff --git a/jps/model/src/org/jetbrains/jps/Project.groovy b/jps/model/src/org/jetbrains/jps/Project.groovy index 82f1e7081bbe..10857b12892e 100644 --- a/jps/model/src/org/jetbrains/jps/Project.groovy +++ b/jps/model/src/org/jetbrains/jps/Project.groovy @@ -1,5 +1,4 @@ package org.jetbrains.jps -import org.jetbrains.jps.artifacts.Artifact /** * @author max */ @@ -7,7 +6,6 @@ class Project { String projectName int locationHash - final Map artifacts = [:] final Map runConfigurations = [:] final CompilerConfiguration compilerConfiguration = new CompilerConfiguration() final UiDesignerConfiguration uiDesignerConfiguration = new UiDesignerConfiguration() diff --git a/jps/model/src/org/jetbrains/jps/ProjectPaths.java b/jps/model/src/org/jetbrains/jps/ProjectPaths.java index b009a5539cf5..b464985de0aa 100644 --- a/jps/model/src/org/jetbrains/jps/ProjectPaths.java +++ b/jps/model/src/org/jetbrains/jps/ProjectPaths.java @@ -10,7 +10,6 @@ import org.jetbrains.jps.model.java.JavaSourceRootType; import org.jetbrains.jps.model.java.JpsJavaClasspathKind; import org.jetbrains.jps.model.java.JpsJavaExtensionService; import org.jetbrains.jps.model.library.JpsLibrary; -import org.jetbrains.jps.model.library.JpsLibraryRoot; import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.module.*; @@ -25,17 +24,10 @@ public class ProjectPaths { private static final String DEFAULT_GENERATED_DIR_NAME = "generated"; @NotNull private final JpsProject myProject; - @Nullable - private final File myProjectTargetDir; //private final Map>> myCachedClasspath = new HashMap>>(); public ProjectPaths(JpsProject project) { - this(project, null); - } - - public ProjectPaths(JpsProject project, @Nullable File projectTargetDir) { myProject = project; - myProjectTargetDir = projectTargetDir; } public Collection getClasspathFiles(JpsModule module, JpsJavaClasspathKind kind) { @@ -114,39 +106,9 @@ public class ProjectPaths { } } - public static void addLibraryFiles(Collection classpath, @Nullable JpsLibrary library) { + private static void addLibraryFiles(Set classpath, @Nullable JpsLibrary library) { if (library != null) { - for (JpsLibraryRoot root : library.getRoots(JpsOrderRootType.COMPILED)) { - final File file = JpsPathUtil.urlToFile(root.getUrl()); - switch (root.getInclusionOptions()) { - case ROOT_ITSELF: - classpath.add(file); - break; - case ARCHIVES_UNDER_ROOT: - collectArchives(file, false, classpath); - break; - case ARCHIVES_UNDER_ROOT_RECURSIVELY: - collectArchives(file, true, classpath); - break; - } - } - } - } - - private static void collectArchives(File file, boolean recursively, Collection result) { - final File[] children = file.listFiles(); - if (children != null) { - for (File child : children) { - final String extension = FileUtil.getExtension(child.getName()); - if (child.isDirectory()) { - if (recursively) { - collectArchives(child, recursively, result); - } - } - else if (extension.equals("jar") || extension.equals("zip")) { - result.add(child); - } - } + classpath.addAll(library.getFiles(JpsOrderRootType.COMPILED)); } } @@ -259,11 +221,6 @@ public class ProjectPaths { @Nullable public File getModuleOutputDir(JpsModule module, boolean forTests) { - if (myProjectTargetDir != null) { - final File basePath = new File(myProjectTargetDir, forTests ? "test" : "production"); - return new File(basePath, module.getName()); - } - final String url = JpsJavaExtensionService.getInstance().getOutputUrl(module, forTests); return url != null ? JpsPathUtil.urlToFile(url) : null; } diff --git a/jps/model/src/org/jetbrains/jps/artifacts/Artifact.groovy b/jps/model/src/org/jetbrains/jps/artifacts/Artifact.groovy deleted file mode 100644 index d8ec4a2f8891..000000000000 --- a/jps/model/src/org/jetbrains/jps/artifacts/Artifact.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package org.jetbrains.jps.artifacts - -/** - * @author nik - */ -class Artifact { - String name - LayoutElement rootElement - String outputPath - Map properties; - - def String toString() { - return "artifact '$name'" - } -} diff --git a/jps/model/src/org/jetbrains/jps/artifacts/ArtifactProperties.groovy b/jps/model/src/org/jetbrains/jps/artifacts/ArtifactProperties.groovy deleted file mode 100644 index dbfbcfee9197..000000000000 --- a/jps/model/src/org/jetbrains/jps/artifacts/ArtifactProperties.groovy +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.jps.artifacts - -/** - * @author nik - */ -interface ArtifactProperties { -} diff --git a/jps/model/src/org/jetbrains/jps/artifacts/ArtifactPropertiesProviderService.groovy b/jps/model/src/org/jetbrains/jps/artifacts/ArtifactPropertiesProviderService.groovy deleted file mode 100644 index 719968d42519..000000000000 --- a/jps/model/src/org/jetbrains/jps/artifacts/ArtifactPropertiesProviderService.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package org.jetbrains.jps.artifacts - -import org.jetbrains.jps.MacroExpander - -/** - * @author nik - */ -abstract class ArtifactPropertiesProviderService

{ - final String id - - ArtifactPropertiesProviderService(String id) { - this.id = id - } - - abstract P loadProperties(Node node, MacroExpander macroExpander) -} diff --git a/jps/model/src/org/jetbrains/jps/artifacts/ComplexLayoutElement.groovy b/jps/model/src/org/jetbrains/jps/artifacts/ComplexLayoutElement.groovy deleted file mode 100644 index 5353a3298b43..000000000000 --- a/jps/model/src/org/jetbrains/jps/artifacts/ComplexLayoutElement.groovy +++ /dev/null @@ -1,79 +0,0 @@ -package org.jetbrains.jps.artifacts - -import org.jetbrains.jps.Project -import org.jetbrains.jps.ProjectPaths -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter -import org.jetbrains.jps.model.JpsModel -import org.jetbrains.jps.model.library.JpsLibrary -import org.jetbrains.jps.model.library.JpsLibraryCollection -/** - * @author nik - */ -abstract class ComplexLayoutElement extends LayoutElement { - abstract List getSubstitution(Project project, JpsModel model) - - boolean process(Project project, JpsModel model, Closure processor) { - if (processor(this)) { - getSubstitution(project, model)*.process(project, model, processor) - } - } -} - -class LibraryFilesElement extends ComplexLayoutElement { - public static final String PROJECT_LEVEL = "project" - String moduleName - String libraryName - String libraryLevel - - List getSubstitution(Project project, JpsModel model) { - JpsLibraryCollection libraries = null - switch (libraryLevel) { - case PROJECT_LEVEL: - libraries = model.project.libraryCollection - break - case "module": - libraries = model.project.modules.find {it.name.equals(moduleName)}?.libraryCollection - break - case "application": - libraries = model.global.libraryCollection - break - } - JpsLibrary library = libraries?.findLibrary(libraryName) - if (library == null) { - return [] - } - - List files = new ArrayList() - ProjectPaths.addLibraryFiles(files, library) - return files.collect {File file -> - if (file.isDirectory()) { - return new DirectoryCopyElement(dirPath: file.absolutePath) - } - else { - return new FileCopyElement(filePath: file.absolutePath) - } - } - } -} - -class ArtifactLayoutElement extends ComplexLayoutElement { - String artifactName - ProjectLoadingErrorReporter errorReporter - - List getSubstitution(Project project, JpsModel model) { - Artifact artifact = project.artifacts[artifactName] - if (artifact == null) { - errorReporter.error("unknown artifact: $artifactName") - return [] - } - def root = artifact.rootElement - if (root instanceof RootElement) { - return ((RootElement)root).children - } - return [root] - } - - Artifact findArtifact(Project project) { - return project.artifacts[artifactName] - } -} diff --git a/jps/model/src/org/jetbrains/jps/artifacts/CompositeLayoutElement.groovy b/jps/model/src/org/jetbrains/jps/artifacts/CompositeLayoutElement.groovy deleted file mode 100644 index f7d0b3b4939b..000000000000 --- a/jps/model/src/org/jetbrains/jps/artifacts/CompositeLayoutElement.groovy +++ /dev/null @@ -1,46 +0,0 @@ -package org.jetbrains.jps.artifacts - -import org.jetbrains.jps.Project -import org.jetbrains.jps.model.JpsModel -/** - * @author nik - */ -abstract class CompositeLayoutElement extends LayoutElement { - String name - protected final List children = [] - - List getChildren() { - return children - } - - LayoutElement leftShift(LayoutElement child) { - children << child - return child - } - - boolean process(Project project, JpsModel model, Closure processor) { - if (processor(this)) { - children*.process(project, model, processor) - } - } -} - -class RootElement extends CompositeLayoutElement { - def RootElement(List children) { - this.children.addAll(children) - } -} - -class DirectoryElement extends CompositeLayoutElement { - def DirectoryElement(String name, List children) { - this.name = name - this.children.addAll(children) - } -} - -class ArchiveElement extends CompositeLayoutElement { - def ArchiveElement(String name, List children) { - this.name = name - this.children.addAll(children) - } -} diff --git a/jps/model/src/org/jetbrains/jps/artifacts/LayoutElement.groovy b/jps/model/src/org/jetbrains/jps/artifacts/LayoutElement.groovy deleted file mode 100644 index 05a30cf1948e..000000000000 --- a/jps/model/src/org/jetbrains/jps/artifacts/LayoutElement.groovy +++ /dev/null @@ -1,49 +0,0 @@ -package org.jetbrains.jps.artifacts -import org.jetbrains.jps.Project -import org.jetbrains.jps.model.JpsModel -/** - * @author nik - */ -abstract class LayoutElement { - boolean process(Project project, JpsModel model, Closure processor) { - return processor(this) - } -} - -class FileCopyElement extends LayoutElement { - String filePath - String outputFileName - - FileCopyElement() { - } - - FileCopyElement(String filePath, String outputFileName) { - this.filePath = filePath - this.outputFileName = outputFileName - } -} - -class DirectoryCopyElement extends LayoutElement { - DirectoryCopyElement() { - } - - DirectoryCopyElement(String dirPath) { - this.dirPath = dirPath - } - - String dirPath -} - -class ExtractedDirectoryElement extends LayoutElement { - String jarPath - String pathInJar -} - -class ModuleOutputElement extends LayoutElement { - String moduleName - -} - -class ModuleTestOutputElement extends LayoutElement { - String moduleName -} diff --git a/jps/model/src/org/jetbrains/jps/artifacts/LayoutElementFactory.groovy b/jps/model/src/org/jetbrains/jps/artifacts/LayoutElementFactory.groovy deleted file mode 100644 index 96cc3c283177..000000000000 --- a/jps/model/src/org/jetbrains/jps/artifacts/LayoutElementFactory.groovy +++ /dev/null @@ -1,18 +0,0 @@ -package org.jetbrains.jps.artifacts - -/** - * @author nik - */ -class LayoutElementFactory { - - static LayoutElement createParentDirectories(String path, LayoutElement element) { - def result = element - path.split("/").reverseEach { - if (it != "") { - result = new DirectoryElement(it, [result]) - } - } - return result - } - -} diff --git a/jps/model/src/org/jetbrains/jps/artifacts/LayoutElementTypeService.java b/jps/model/src/org/jetbrains/jps/artifacts/LayoutElementTypeService.java deleted file mode 100644 index a9c15ffe72e1..000000000000 --- a/jps/model/src/org/jetbrains/jps/artifacts/LayoutElementTypeService.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.jetbrains.jps.artifacts; - -import groovy.util.Node; -import org.jetbrains.jps.MacroExpander; -import org.jetbrains.jps.Project; -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter; - -/** - * @author nik - */ -public abstract class LayoutElementTypeService { - private final String typeId; - - protected LayoutElementTypeService(String typeId) { - this.typeId = typeId; - } - - public String getTypeId() { - return typeId; - } - - public abstract LayoutElement createElement(Project project, Node tag, MacroExpander macroExpander, ProjectLoadingErrorReporter errorReporter); -} diff --git a/jps/model/src/org/jetbrains/jps/idea/ArtifactLoader.groovy b/jps/model/src/org/jetbrains/jps/idea/ArtifactLoader.groovy deleted file mode 100644 index a99a37bbc4dd..000000000000 --- a/jps/model/src/org/jetbrains/jps/idea/ArtifactLoader.groovy +++ /dev/null @@ -1,125 +0,0 @@ -package org.jetbrains.jps.idea - -import org.jetbrains.jps.MacroExpander -import org.jetbrains.jps.Project -import org.jetbrains.jps.artifacts.* - - /** - * @author nik - */ -class ArtifactLoader { - private final Project project - private final MacroExpander macroExpander - private static OwnServiceLoader elementTypeLoader = OwnServiceLoader.load(LayoutElementTypeService.class) - private static OwnServiceLoader propertiesProvidersLoader = OwnServiceLoader.load(ArtifactPropertiesProviderService.class) - private static Map elementTypes = null - private static Map propertiesProviders = null - private final ProjectLoadingErrorReporter errorReporter - - def ArtifactLoader(Project project, MacroExpander macroExpander, ProjectLoadingErrorReporter errorReporter) { - this.macroExpander = macroExpander - this.project = project - this.errorReporter = errorReporter - } - - LayoutElement loadLayoutElement(Node tag, String artifactName) { - String id = tag."@id"; - switch (id) { - case "root": - return new RootElement(loadChildren(tag, artifactName)); - case "directory": - return new DirectoryElement(tag."@name", loadChildren(tag, artifactName)); - case "archive": - return new ArchiveElement(tag."@name", loadChildren(tag, artifactName)); - case "artifact": - return new ArtifactLayoutElement(artifactName: tag."@artifact-name", errorReporter: errorReporter) - case "file-copy": - def path = macroExpander.expandMacros(tag."@path") - if (!new File(path).exists()) { - errorReporter.warning("Error in '$artifactName' artifact: file '$path' doesn't exist") - } - return new FileCopyElement(filePath: path, - outputFileName: tag."@output-file-name"); - case "dir-copy": - def path = macroExpander.expandMacros(tag."@path") - if (!new File(path).exists()) { - errorReporter.warning("Error in '$artifactName' artifact: directory '$path' doesn't exist") - } - return new DirectoryCopyElement(dirPath: path); - case "extracted-dir": - def jarPath = macroExpander.expandMacros(tag."@path") - String pathInJar = tag."@path-in-jar" - if (pathInJar == null) pathInJar = "/" - if (!new File(jarPath).exists()) { - errorReporter.warning("Error in '$artifactName' artifact: file '$jarPath' doesn't exist") - } - return new ExtractedDirectoryElement(jarPath: jarPath, pathInJar: pathInJar) - case "module-output": - def name = tag."@name" - return new ModuleOutputElement(moduleName: name); - case "module-test-output": - def name = tag."@name" - return new ModuleTestOutputElement(moduleName: name); - case "library": - return new LibraryFilesElement(libraryLevel: tag."@level", libraryName: tag."@name", moduleName: tag."@module-name"); - } - - LayoutElementTypeService type = findType(id) - if (type != null) { - return type.createElement(project, tag, macroExpander, errorReporter) - } - - errorReporter.error("unknown element in '$artifactName' artifact: $id"); - return null - } - - private LayoutElementTypeService findType(String typeId) { - if (elementTypes == null) { - elementTypes = [:] - elementTypeLoader.each {LayoutElementTypeService type -> - elementTypes[type.typeId] = type - } - } - return elementTypes[typeId] - } - - private ArtifactPropertiesProviderService findPropertiesProvider(String id) { - if (propertiesProviders == null) { - propertiesProviders = [:] - propertiesProvidersLoader.each {ArtifactPropertiesProviderService provider -> - propertiesProviders[provider.id] = provider - } - } - return propertiesProviders[id] - } - - Map loadOptions(Node artifactTag, String artifactName) { - def Map res = [:]; - artifactTag.properties.each {Node propertiesNode -> - def String id = propertiesNode."@id"; - ArtifactPropertiesProviderService provider = findPropertiesProvider(id) - if (provider != null) { - try { - res[id] = provider.loadProperties(propertiesNode.options[0], macroExpander) - } catch (Exception e) { - errorReporter.warning("Failed to load properties of the artifact: $artifactName, error: " + e.getMessage()); - } - } - else { - errorReporter.warning("Unknown properties '$id' in '$artifactName' artifact") - } - } - return res; - } - - List loadChildren(Node node, String artifactName) { - List children = [] - node.element.each { - def child = loadLayoutElement(it, artifactName) - if (child != null) { - children << child - } - } - return children - } -} diff --git a/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy b/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy index 473eb6304c03..3aa7f6e3cee6 100644 --- a/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy +++ b/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy @@ -2,7 +2,6 @@ package org.jetbrains.jps.idea import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import org.jetbrains.jps.* -import org.jetbrains.jps.artifacts.Artifact /** * @author max */ @@ -84,7 +83,6 @@ public class IdeaProjectLoader { loadProjectFileEncodings(root) loadWorkspaceConfiguration(new File(iprFile.parentFile, iprFile.name[0..-4]+"iws")) loadUiDesignerConfiguration(root) - loadArtifacts(getComponent(root, "ArtifactManager")) loadRunConfigurations(getComponent(root, "ProjectRunConfigurationManager")) } @@ -109,16 +107,6 @@ public class IdeaProjectLoader { loadUiDesignerConfiguration(xmlParser.parse(uiDesignerXml)) } - def artifactsFolder = new File(dir, "artifacts") - if (artifactsFolder.isDirectory()) { - artifactsFolder.eachFile {File file -> - if (isXmlFile(file)) { - def artifactsComponent = xmlParser.parse(file) - loadArtifacts(artifactsComponent) - } - } - } - def runConfFolder = new File(dir, "runConfigurations") if (runConfFolder.isDirectory()) { runConfFolder.eachFile {File file -> @@ -296,19 +284,6 @@ public class IdeaProjectLoader { } } - def loadArtifacts(Node artifactsComponent) { - if (artifactsComponent == null) return; - ArtifactLoader artifactLoader = new ArtifactLoader(project, projectMacroExpander, errorReporter) - artifactsComponent.artifact.each {Node artifactTag -> - def artifactName = artifactTag."@name" - def outputPath = projectMacroExpander.expandMacros(artifactTag."output-path"[0]?.text()) - def root = artifactLoader.loadLayoutElement(artifactTag.root[0], artifactName) - def options = artifactLoader.loadOptions(artifactTag, artifactName) - def artifact = new Artifact(name: artifactName, rootElement: root, outputPath: outputPath, properties: options); - project.artifacts[artifact.name] = artifact; - } - } - def loadRunConfigurations(Node runConfManager) { if (runConfManager == null) return; diff --git a/native/IdeaWin32/IdeaWin32.cpp b/native/IdeaWin32/IdeaWin32.cpp index 8dd09c310cb1..4db3aad0fe4b 100644 --- a/native/IdeaWin32/IdeaWin32.cpp +++ b/native/IdeaWin32/IdeaWin32.cpp @@ -1,18 +1,30 @@ -#include "stdafx.h" +/* + * Copyright 2000-2012 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. + */ + #include "IdeaWin32.h" -#include "jni_util.h" -#include "windows.h" +#include -jfieldID nameID; -jfieldID attributesID; -jfieldID timestampID; -jfieldID lengthID; -JNIEXPORT void JNICALL Java_com_intellij_openapi_vfs_impl_win32_FileInfo_initIDs(JNIEnv *env, jclass cls) { - nameID = env->GetFieldID(cls, "name", "Ljava/lang/String;"); - attributesID = env->GetFieldID(cls, "attributes", "I"); - timestampID = env->GetFieldID(cls, "timestamp", "J"); - lengthID = env->GetFieldID(cls, "length", "J"); +static jfieldID nameID = NULL; +static jfieldID attributesID = NULL; +static jfieldID timestampID = NULL; +static jfieldID lengthID = NULL; + +static jclass getFileInfoClass(JNIEnv *env) { + return env->FindClass("com/intellij/openapi/util/io/win32/FileInfo"); } static HANDLE FindFileInner(JNIEnv *env, jstring path, LPWIN32_FIND_DATA lpData) { @@ -31,7 +43,7 @@ static bool CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src, jin return true; } -static LONGLONG pairToInt64(DWORD lowPart, DWORD highPart) { +static inline LONGLONG pairToInt64(DWORD lowPart, DWORD highPart) { ULARGE_INTEGER large; large.LowPart = lowPart; large.HighPart = highPart; @@ -39,9 +51,10 @@ static LONGLONG pairToInt64(DWORD lowPart, DWORD highPart) { } #define IS_SET(flags, flag) ((flags & flag) == flag) +#define FILE_SHARE_ATTRIBUTES (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) -static jobject CreateFileInfo(JNIEnv *env, jstring path, bool append, LPWIN32_FIND_DATA lpData, jclass cls) { - jobject o = env->AllocObject(cls); +static jobject CreateFileInfo(JNIEnv *env, jstring path, bool append, LPWIN32_FIND_DATA lpData, jclass fileInfoClass) { + jobject o = env->AllocObject(fileInfoClass); if (o == NULL) { return NULL; } @@ -53,34 +66,39 @@ static jobject CreateFileInfo(JNIEnv *env, jstring path, bool append, LPWIN32_FI env->SetObjectField(o, nameID, fileName); bool read = false; - if (IS_SET(lpData->dwFileAttributes, FILE_ATTRIBUTE_REPARSE_POINT) && IS_SET(lpData->dwReserved0, IO_REPARSE_TAG_SYMLINK)) { - int nameLen = env->GetStringLength(path) + wcslen(lpData->cFileName) + 2; - wchar_t *lpName = (wchar_t *)malloc(nameLen * sizeof(wchar_t)); + if (IS_SET(lpData->dwFileAttributes, FILE_ATTRIBUTE_REPARSE_POINT)) { + if (IS_SET(lpData->dwReserved0, IO_REPARSE_TAG_SYMLINK)) { + size_t nameLen = env->GetStringLength(path) + wcslen(lpData->cFileName) + 2; + wchar_t *lpName = (wchar_t *)malloc(nameLen * sizeof(wchar_t)); - if (lpName != NULL) { - const jchar *dirName = env->GetStringChars(path, 0); - wcscpy_s(lpName, nameLen, (LPCWSTR)dirName); - env->ReleaseStringChars(path, dirName); - if (append) { - wcscat_s(lpName, nameLen, L"\\"); - wcscat_s(lpName, nameLen, lpData->cFileName); - } - - // read symlink target attributes - HANDLE th = CreateFile(lpName, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (th != INVALID_HANDLE_VALUE) { - BY_HANDLE_FILE_INFORMATION targetData; - if (GetFileInformationByHandle(th, &targetData)) { - env->SetIntField(o, attributesID, targetData.dwFileAttributes); - env->SetLongField(o, timestampID, pairToInt64(targetData.ftLastWriteTime.dwLowDateTime, targetData.ftLastWriteTime.dwHighDateTime)); - env->SetLongField(o, lengthID, pairToInt64(targetData.nFileSizeLow, targetData.nFileSizeHigh)); - read = true; + if (lpName != NULL) { + const jchar *dirName = env->GetStringChars(path, 0); + wcscpy_s(lpName, nameLen, (LPCWSTR)dirName); + env->ReleaseStringChars(path, dirName); + if (append) { + wcscat_s(lpName, nameLen, L"\\"); + wcscat_s(lpName, nameLen, lpData->cFileName); } - CloseHandle(th); - } - free(lpName); + // read symlink target attributes + HANDLE th = CreateFile(lpName, 0, FILE_SHARE_ATTRIBUTES, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (th != INVALID_HANDLE_VALUE) { + BY_HANDLE_FILE_INFORMATION targetData; + if (GetFileInformationByHandle(th, &targetData)) { + targetData.dwFileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT; + env->SetIntField(o, attributesID, targetData.dwFileAttributes); + env->SetLongField(o, timestampID, pairToInt64(targetData.ftLastWriteTime.dwLowDateTime, targetData.ftLastWriteTime.dwHighDateTime)); + env->SetLongField(o, lengthID, pairToInt64(targetData.nFileSizeLow, targetData.nFileSizeHigh)); + read = true; + } + CloseHandle(th); + } + + free(lpName); + } + } + else { + lpData->dwFileAttributes &= (~ FILE_ATTRIBUTE_REPARSE_POINT); // keep reparse flag only for symlinks } } @@ -93,28 +111,97 @@ static jobject CreateFileInfo(JNIEnv *env, jstring path, bool append, LPWIN32_FI return o; } -JNIEXPORT jobject JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path) { + +JNIEXPORT void JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_initIDs(JNIEnv *env, jclass cls) { + jclass fileInfoClass = getFileInfoClass(env); + if (fileInfoClass == NULL) { + return; + } + + nameID = env->GetFieldID(fileInfoClass, "name", "Ljava/lang/String;"); + attributesID = env->GetFieldID(fileInfoClass, "attributes", "I"); + timestampID = env->GetFieldID(fileInfoClass, "timestamp", "J"); + lengthID = env->GetFieldID(fileInfoClass, "length", "J"); +} + + +JNIEXPORT jobject JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path) { + WIN32_FIND_DATA data; + HANDLE h = FindFileInner(env, path, &data); + if (h == INVALID_HANDLE_VALUE) { + return NULL; + } + + FindClose(h); + + jclass fileInfoClass = getFileInfoClass(env); + if (fileInfoClass == NULL) { + return NULL; + } + + return CreateFileInfo(env, path, false, &data, fileInfoClass); +} + + +JNIEXPORT jstring JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_resolveSymLink(JNIEnv *env, jobject method, jstring path) { WIN32_FIND_DATA data; HANDLE h = FindFileInner(env, path, &data); if (h == INVALID_HANDLE_VALUE) { return NULL; } FindClose(h); - jclass infoClass = env->FindClass("com/intellij/openapi/vfs/impl/win32/FileInfo"); - return CreateFileInfo(env, path, false, &data, infoClass); + + if (!IS_SET(data.dwFileAttributes, FILE_ATTRIBUTE_REPARSE_POINT) || !IS_SET(data.dwReserved0, IO_REPARSE_TAG_SYMLINK)) { + return NULL; + } + + const jchar* str = env->GetStringChars(path, 0); + HANDLE th = CreateFile((LPCWSTR)str, 0, FILE_SHARE_ATTRIBUTES, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + env->ReleaseStringChars(path, str); + if (th == INVALID_HANDLE_VALUE) { + return NULL; + } + + jstring result = NULL; + + TCHAR name[MAX_PATH]; + DWORD len = GetFinalPathNameByHandle(th, name, MAX_PATH, 0); + if (len > 0) { + if (len < MAX_PATH) { + result = env->NewString((jchar *)name, len); + } + else { + TCHAR *name = (TCHAR *)malloc(sizeof(TCHAR) * (len + 1)); + if (name != NULL) { + len = GetFinalPathNameByHandle(th, name, len, 0); + if (len > 0) { + result = env->NewString((jchar *)name, len); + } + free(name); + } + } + } + + CloseHandle(th); + return result; } -JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path) { + +JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path) { WIN32_FIND_DATA data; HANDLE h = FindFileInner(env, path, &data); if (h == INVALID_HANDLE_VALUE) { return NULL; } + jclass fileInfoClass = getFileInfoClass(env); + if (fileInfoClass == NULL) { + return NULL; + } + jobjectArray rv, old; int len = 0, maxlen = 16; - jclass infoClass = env->FindClass("com/intellij/openapi/vfs/impl/win32/FileInfo"); - rv = env->NewObjectArray(maxlen, infoClass, NULL); + rv = env->NewObjectArray(maxlen, fileInfoClass, NULL); if (rv == NULL) { goto error; } @@ -122,13 +209,13 @@ JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin3 do { if (len == maxlen) { old = rv; - rv = env->NewObjectArray(maxlen <<= 1, infoClass, NULL); + rv = env->NewObjectArray(maxlen <<= 1, fileInfoClass, NULL); if (rv == NULL || !CopyObjectArray(env, rv, old, len)) { goto error; } env->DeleteLocalRef(old); } - jobject o = CreateFileInfo(env, path, true, &data, infoClass); + jobject o = CreateFileInfo(env, path, true, &data, fileInfoClass); env->SetObjectArrayElement(rv, len++, o); env->DeleteLocalRef(o); } @@ -137,7 +224,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin3 FindClose(h); old = rv; - rv = env->NewObjectArray(len, infoClass, NULL); + rv = env->NewObjectArray(len, fileInfoClass, NULL); if (rv == NULL || !CopyObjectArray(env, rv, old, len)) { goto error; } @@ -148,6 +235,7 @@ error: return NULL; } -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { return TRUE; } diff --git a/native/IdeaWin32/IdeaWin32.h b/native/IdeaWin32/IdeaWin32.h index 2fe5bd16e17d..67173207e1f1 100644 --- a/native/IdeaWin32/IdeaWin32.h +++ b/native/IdeaWin32/IdeaWin32.h @@ -1,15 +1,40 @@ -#include "jni.h" +/* + * Copyright 2000-2012 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. + */ +#include + +#ifndef _Included_com_intellij_openapi_util_io_win32_IdeaWin32 +#define _Included_com_intellij_openapi_util_io_win32_IdeaWin32 #ifdef __cplusplus extern "C" { #endif -JNIEXPORT void JNICALL Java_com_intellij_openapi_vfs_impl_win32_FileInfo_initIDs(JNIEnv *env, jclass cls); +JNIEXPORT void JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_initIDs + (JNIEnv *, jclass); -JNIEXPORT jobject JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path); +JNIEXPORT jobject JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_getInfo + (JNIEnv *, jobject, jstring); -JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path); +JNIEXPORT jstring JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_resolveSymLink + (JNIEnv *, jobject, jstring); + +JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_listChildren + (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif +#endif diff --git a/native/IdeaWin32/IdeaWin32.props b/native/IdeaWin32/IdeaWin32.props new file mode 100644 index 000000000000..467d726981e9 --- /dev/null +++ b/native/IdeaWin32/IdeaWin32.props @@ -0,0 +1,17 @@ + + + + + C:\Tools\JDK6 + + + $(Configuration)$(Platform)\ + $(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include;$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32 + + + + + $(JAVA_HOME) + + + \ No newline at end of file diff --git a/native/IdeaWin32/IdeaWin32.sln b/native/IdeaWin32/IdeaWin32.sln index fd410bf12728..05286e510063 100644 --- a/native/IdeaWin32/IdeaWin32.sln +++ b/native/IdeaWin32/IdeaWin32.sln @@ -1,18 +1,24 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IdeaWin32", "IdeaWin32.vcproj", "{D1A0CC4B-C100-46E4-918A-958626AE1ACF}" +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IdeaWin32", "IdeaWin32.vcxproj", "{F68FFBFC-3437-4215-839A-563936B9A3CC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D1A0CC4B-C100-46E4-918A-958626AE1ACF}.Debug|Win32.ActiveCfg = Debug|Win32 - {D1A0CC4B-C100-46E4-918A-958626AE1ACF}.Debug|Win32.Build.0 = Debug|Win32 - {D1A0CC4B-C100-46E4-918A-958626AE1ACF}.Release|Win32.ActiveCfg = Release|Win32 - {D1A0CC4B-C100-46E4-918A-958626AE1ACF}.Release|Win32.Build.0 = Release|Win32 + {F68FFBFC-3437-4215-839A-563936B9A3CC}.Debug|Win32.ActiveCfg = Debug|Win32 + {F68FFBFC-3437-4215-839A-563936B9A3CC}.Debug|Win32.Build.0 = Debug|Win32 + {F68FFBFC-3437-4215-839A-563936B9A3CC}.Debug|x64.ActiveCfg = Debug|x64 + {F68FFBFC-3437-4215-839A-563936B9A3CC}.Debug|x64.Build.0 = Debug|x64 + {F68FFBFC-3437-4215-839A-563936B9A3CC}.Release|Win32.ActiveCfg = Release|Win32 + {F68FFBFC-3437-4215-839A-563936B9A3CC}.Release|Win32.Build.0 = Release|Win32 + {F68FFBFC-3437-4215-839A-563936B9A3CC}.Release|x64.ActiveCfg = Release|x64 + {F68FFBFC-3437-4215-839A-563936B9A3CC}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/native/IdeaWin32/IdeaWin32.vcproj b/native/IdeaWin32/IdeaWin32.vcproj deleted file mode 100644 index 4f26b1821867..000000000000 --- a/native/IdeaWin32/IdeaWin32.vcproj +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/native/IdeaWin32/IdeaWin32.vcxproj b/native/IdeaWin32/IdeaWin32.vcxproj new file mode 100644 index 000000000000..bdf7114484b6 --- /dev/null +++ b/native/IdeaWin32/IdeaWin32.vcxproj @@ -0,0 +1,162 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F68FFBFC-3437-4215-839A-563936B9A3CC} + Win32Proj + IdeaWin32 + + + + DynamicLibrary + true + Unicode + Windows7.1SDK + + + DynamicLibrary + true + Unicode + Windows7.1SDK + + + DynamicLibrary + false + true + Unicode + Windows7.1SDK + + + DynamicLibrary + false + true + Unicode + Windows7.1SDK + + + + + + + + + + + + + + + + + + + + + + + false + $(Configuration)$(Platform)\ + IdeaWin32 + + + false + $(Configuration)$(Platform)\ + IdeaWin64 + + + false + $(Configuration)$(Platform)\ + IdeaWin32 + + + false + $(Configuration)$(Platform)\ + IdeaWin64 + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEAWIN32_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebug + + + Windows + true + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEAWIN32_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebug + + + Windows + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEAWIN32_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Windows + true + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEAWIN32_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Windows + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/native/IdeaWin32/IdeaWin32.vcxproj.filters b/native/IdeaWin32/IdeaWin32.vcxproj.filters new file mode 100644 index 000000000000..cf3b94ffcf16 --- /dev/null +++ b/native/IdeaWin32/IdeaWin32.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/native/IdeaWin32/IdeaWin32.vcxproj.user b/native/IdeaWin32/IdeaWin32.vcxproj.user new file mode 100644 index 000000000000..ace9a86acb77 --- /dev/null +++ b/native/IdeaWin32/IdeaWin32.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/native/IdeaWin32/jlong.h b/native/IdeaWin32/jlong.h deleted file mode 100644 index d3fe33fd58c7..000000000000 --- a/native/IdeaWin32/jlong.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -#ifndef _JLONG_H_ -#define _JLONG_H_ - -#include "jlong_md.h" - -#endif diff --git a/native/IdeaWin32/jlong_md.h b/native/IdeaWin32/jlong_md.h deleted file mode 100644 index 8b62f26c37e1..000000000000 --- a/native/IdeaWin32/jlong_md.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -#ifndef _WIN32_JLONG_MD_H_ -#define _WIN32_JLONG_MD_H_ - -/* Make sure ptrdiff_t is defined */ -#include - -#define jlong_high(a) ((jint)((a)>>32)) -#define jlong_low(a) ((jint)(a)) -#define jlong_add(a, b) ((a) + (b)) -#define jlong_and(a, b) ((a) & (b)) -#define jlong_div(a, b) ((a) / (b)) -#define jlong_mul(a, b) ((a) * (b)) -#define jlong_neg(a) (-(a)) -#define jlong_not(a) (~(a)) -#define jlong_or(a, b) ((a) | (b)) -#define jlong_shl(a, n) ((a) << (n)) -#define jlong_shr(a, n) ((a) >> (n)) -#define jlong_sub(a, b) ((a) - (b)) -#define jlong_xor(a, b) ((a) ^ (b)) -#define jlong_rem(a,b) ((a) % (b)) - -/* comparison operators */ -#define jlong_ltz(ll) ((ll) < 0) -#define jlong_gez(ll) ((ll) >= 0) -#define jlong_gtz(ll) ((ll) > 0) -#define jlong_eqz(a) ((a) == 0) -#define jlong_eq(a, b) ((a) == (b)) -#define jlong_ne(a,b) ((a) != (b)) -#define jlong_ge(a,b) ((a) >= (b)) -#define jlong_le(a,b) ((a) <= (b)) -#define jlong_lt(a,b) ((a) < (b)) -#define jlong_gt(a,b) ((a) > (b)) - -#define jlong_zero ((jlong) 0) -#define jlong_one ((jlong) 1) -#define jlong_minus_one ((jlong) -1) - -/* For static variables initialized to zero */ -#define jlong_zero_init ((jlong) 0) - -#ifdef _WIN64 -#define jlong_to_ptr(a) ((void*)(a)) -#define ptr_to_jlong(a) ((jlong)(a)) -#else -/* Double casting to avoid warning messages looking for casting of */ -/* smaller sizes into pointers */ -#define jlong_to_ptr(a) ((void*)(int)(a)) -#define ptr_to_jlong(a) ((jlong)(int)(a)) -#endif - -#define jint_to_jlong(a) ((jlong)(a)) -#define jlong_to_jint(a) ((jint)(a)) - -/* Useful on machines where jlong and jdouble have different endianness. */ -#define jlong_to_jdouble_bits(a) -#define jdouble_to_jlong_bits(a) - -#define jlong_to_int(a) ((int)(a)) -#define int_to_jlong(a) ((jlong)(a)) -#define jlong_to_uint(a) ((unsigned int)(a)) -#define uint_to_jlong(a) ((jlong)(a)) -#define jlong_to_ptrdiff(a) ((ptrdiff_t)(a)) -#define ptrdiff_to_jlong(a) ((jlong)(a)) -#define jlong_to_size(a) ((size_t)(a)) -#define size_to_jlong(a) ((jlong)(a)) -#define long_to_jlong(a) ((jlong)(a)) - -#endif diff --git a/native/IdeaWin32/jni.h b/native/IdeaWin32/jni.h deleted file mode 100644 index f53476c09671..000000000000 --- a/native/IdeaWin32/jni.h +++ /dev/null @@ -1,1944 +0,0 @@ -/* - * @(#)jni.h 1.62 06/02/02 - * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -/* - * We used part of Netscape's Java Runtime Interface (JRI) as the starting - * point of our design and implementation. - */ - -/****************************************************************************** - * Java Runtime Interface - * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. - *****************************************************************************/ - -#ifndef _JAVASOFT_JNI_H_ -#define _JAVASOFT_JNI_H_ - -#include -#include - -/* jni_md.h contains the machine-dependent typedefs for jbyte, jint - and jlong */ - -#include "jni_md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * JNI Types - */ - -#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H - -typedef unsigned char jboolean; -typedef unsigned short jchar; -typedef short jshort; -typedef float jfloat; -typedef double jdouble; - -typedef jint jsize; - -#ifdef __cplusplus - -class _jobject {}; -class _jclass : public _jobject {}; -class _jthrowable : public _jobject {}; -class _jstring : public _jobject {}; -class _jarray : public _jobject {}; -class _jbooleanArray : public _jarray {}; -class _jbyteArray : public _jarray {}; -class _jcharArray : public _jarray {}; -class _jshortArray : public _jarray {}; -class _jintArray : public _jarray {}; -class _jlongArray : public _jarray {}; -class _jfloatArray : public _jarray {}; -class _jdoubleArray : public _jarray {}; -class _jobjectArray : public _jarray {}; - -typedef _jobject *jobject; -typedef _jclass *jclass; -typedef _jthrowable *jthrowable; -typedef _jstring *jstring; -typedef _jarray *jarray; -typedef _jbooleanArray *jbooleanArray; -typedef _jbyteArray *jbyteArray; -typedef _jcharArray *jcharArray; -typedef _jshortArray *jshortArray; -typedef _jintArray *jintArray; -typedef _jlongArray *jlongArray; -typedef _jfloatArray *jfloatArray; -typedef _jdoubleArray *jdoubleArray; -typedef _jobjectArray *jobjectArray; - -#else - -struct _jobject; - -typedef struct _jobject *jobject; -typedef jobject jclass; -typedef jobject jthrowable; -typedef jobject jstring; -typedef jobject jarray; -typedef jarray jbooleanArray; -typedef jarray jbyteArray; -typedef jarray jcharArray; -typedef jarray jshortArray; -typedef jarray jintArray; -typedef jarray jlongArray; -typedef jarray jfloatArray; -typedef jarray jdoubleArray; -typedef jarray jobjectArray; - -#endif - -typedef jobject jweak; - -typedef union jvalue { - jboolean z; - jbyte b; - jchar c; - jshort s; - jint i; - jlong j; - jfloat f; - jdouble d; - jobject l; -} jvalue; - -struct _jfieldID; -typedef struct _jfieldID *jfieldID; - -struct _jmethodID; -typedef struct _jmethodID *jmethodID; - -/* Return values from jobjectRefType */ -typedef enum _jobjectType { - JNIInvalidRefType = 0, - JNILocalRefType = 1, - JNIGlobalRefType = 2, - JNIWeakGlobalRefType = 3 -} jobjectRefType; - - -#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ - -/* - * jboolean constants - */ - -#define JNI_FALSE 0 -#define JNI_TRUE 1 - -/* - * possible return values for JNI functions. - */ - -#define JNI_OK 0 /* success */ -#define JNI_ERR (-1) /* unknown error */ -#define JNI_EDETACHED (-2) /* thread detached from the VM */ -#define JNI_EVERSION (-3) /* JNI version error */ -#define JNI_ENOMEM (-4) /* not enough memory */ -#define JNI_EEXIST (-5) /* VM already created */ -#define JNI_EINVAL (-6) /* invalid arguments */ - -/* - * used in ReleaseScalarArrayElements - */ - -#define JNI_COMMIT 1 -#define JNI_ABORT 2 - -/* - * used in RegisterNatives to describe native method name, signature, - * and function pointer. - */ - -typedef struct { - char *name; - char *signature; - void *fnPtr; -} JNINativeMethod; - -/* - * JNI Native Method Interface. - */ - -struct JNINativeInterface_; - -struct JNIEnv_; - -#ifdef __cplusplus -typedef JNIEnv_ JNIEnv; -#else -typedef const struct JNINativeInterface_ *JNIEnv; -#endif - -/* - * JNI Invocation Interface. - */ - -struct JNIInvokeInterface_; - -struct JavaVM_; - -#ifdef __cplusplus -typedef JavaVM_ JavaVM; -#else -typedef const struct JNIInvokeInterface_ *JavaVM; -#endif - -struct JNINativeInterface_ { - void *reserved0; - void *reserved1; - void *reserved2; - - void *reserved3; - jint (JNICALL *GetVersion)(JNIEnv *env); - - jclass (JNICALL *DefineClass) - (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, - jsize len); - jclass (JNICALL *FindClass) - (JNIEnv *env, const char *name); - - jmethodID (JNICALL *FromReflectedMethod) - (JNIEnv *env, jobject method); - jfieldID (JNICALL *FromReflectedField) - (JNIEnv *env, jobject field); - - jobject (JNICALL *ToReflectedMethod) - (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); - - jclass (JNICALL *GetSuperclass) - (JNIEnv *env, jclass sub); - jboolean (JNICALL *IsAssignableFrom) - (JNIEnv *env, jclass sub, jclass sup); - - jobject (JNICALL *ToReflectedField) - (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); - - jint (JNICALL *Throw) - (JNIEnv *env, jthrowable obj); - jint (JNICALL *ThrowNew) - (JNIEnv *env, jclass clazz, const char *msg); - jthrowable (JNICALL *ExceptionOccurred) - (JNIEnv *env); - void (JNICALL *ExceptionDescribe) - (JNIEnv *env); - void (JNICALL *ExceptionClear) - (JNIEnv *env); - void (JNICALL *FatalError) - (JNIEnv *env, const char *msg); - - jint (JNICALL *PushLocalFrame) - (JNIEnv *env, jint capacity); - jobject (JNICALL *PopLocalFrame) - (JNIEnv *env, jobject result); - - jobject (JNICALL *NewGlobalRef) - (JNIEnv *env, jobject lobj); - void (JNICALL *DeleteGlobalRef) - (JNIEnv *env, jobject gref); - void (JNICALL *DeleteLocalRef) - (JNIEnv *env, jobject obj); - jboolean (JNICALL *IsSameObject) - (JNIEnv *env, jobject obj1, jobject obj2); - jobject (JNICALL *NewLocalRef) - (JNIEnv *env, jobject ref); - jint (JNICALL *EnsureLocalCapacity) - (JNIEnv *env, jint capacity); - - jobject (JNICALL *AllocObject) - (JNIEnv *env, jclass clazz); - jobject (JNICALL *NewObject) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jobject (JNICALL *NewObjectV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jobject (JNICALL *NewObjectA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jclass (JNICALL *GetObjectClass) - (JNIEnv *env, jobject obj); - jboolean (JNICALL *IsInstanceOf) - (JNIEnv *env, jobject obj, jclass clazz); - - jmethodID (JNICALL *GetMethodID) - (JNIEnv *env, jclass clazz, const char *name, const char *sig); - - jobject (JNICALL *CallObjectMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jobject (JNICALL *CallObjectMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jobject (JNICALL *CallObjectMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); - - jboolean (JNICALL *CallBooleanMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jboolean (JNICALL *CallBooleanMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jboolean (JNICALL *CallBooleanMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); - - jbyte (JNICALL *CallByteMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jbyte (JNICALL *CallByteMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jbyte (JNICALL *CallByteMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); - - jchar (JNICALL *CallCharMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jchar (JNICALL *CallCharMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jchar (JNICALL *CallCharMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); - - jshort (JNICALL *CallShortMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jshort (JNICALL *CallShortMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jshort (JNICALL *CallShortMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); - - jint (JNICALL *CallIntMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jint (JNICALL *CallIntMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jint (JNICALL *CallIntMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); - - jlong (JNICALL *CallLongMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jlong (JNICALL *CallLongMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jlong (JNICALL *CallLongMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); - - jfloat (JNICALL *CallFloatMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jfloat (JNICALL *CallFloatMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jfloat (JNICALL *CallFloatMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); - - jdouble (JNICALL *CallDoubleMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - jdouble (JNICALL *CallDoubleMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - jdouble (JNICALL *CallDoubleMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); - - void (JNICALL *CallVoidMethod) - (JNIEnv *env, jobject obj, jmethodID methodID, ...); - void (JNICALL *CallVoidMethodV) - (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); - void (JNICALL *CallVoidMethodA) - (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); - - jobject (JNICALL *CallNonvirtualObjectMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jobject (JNICALL *CallNonvirtualObjectMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jobject (JNICALL *CallNonvirtualObjectMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue * args); - - jboolean (JNICALL *CallNonvirtualBooleanMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jboolean (JNICALL *CallNonvirtualBooleanMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jboolean (JNICALL *CallNonvirtualBooleanMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue * args); - - jbyte (JNICALL *CallNonvirtualByteMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jbyte (JNICALL *CallNonvirtualByteMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jbyte (JNICALL *CallNonvirtualByteMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue *args); - - jchar (JNICALL *CallNonvirtualCharMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jchar (JNICALL *CallNonvirtualCharMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jchar (JNICALL *CallNonvirtualCharMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue *args); - - jshort (JNICALL *CallNonvirtualShortMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jshort (JNICALL *CallNonvirtualShortMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jshort (JNICALL *CallNonvirtualShortMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue *args); - - jint (JNICALL *CallNonvirtualIntMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jint (JNICALL *CallNonvirtualIntMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jint (JNICALL *CallNonvirtualIntMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue *args); - - jlong (JNICALL *CallNonvirtualLongMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jlong (JNICALL *CallNonvirtualLongMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jlong (JNICALL *CallNonvirtualLongMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue *args); - - jfloat (JNICALL *CallNonvirtualFloatMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jfloat (JNICALL *CallNonvirtualFloatMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jfloat (JNICALL *CallNonvirtualFloatMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue *args); - - jdouble (JNICALL *CallNonvirtualDoubleMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - jdouble (JNICALL *CallNonvirtualDoubleMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - jdouble (JNICALL *CallNonvirtualDoubleMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue *args); - - void (JNICALL *CallNonvirtualVoidMethod) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); - void (JNICALL *CallNonvirtualVoidMethodV) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - va_list args); - void (JNICALL *CallNonvirtualVoidMethodA) - (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, - const jvalue * args); - - jfieldID (JNICALL *GetFieldID) - (JNIEnv *env, jclass clazz, const char *name, const char *sig); - - jobject (JNICALL *GetObjectField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - jboolean (JNICALL *GetBooleanField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - jbyte (JNICALL *GetByteField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - jchar (JNICALL *GetCharField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - jshort (JNICALL *GetShortField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - jint (JNICALL *GetIntField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - jlong (JNICALL *GetLongField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - jfloat (JNICALL *GetFloatField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - jdouble (JNICALL *GetDoubleField) - (JNIEnv *env, jobject obj, jfieldID fieldID); - - void (JNICALL *SetObjectField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); - void (JNICALL *SetBooleanField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); - void (JNICALL *SetByteField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); - void (JNICALL *SetCharField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); - void (JNICALL *SetShortField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); - void (JNICALL *SetIntField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); - void (JNICALL *SetLongField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); - void (JNICALL *SetFloatField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); - void (JNICALL *SetDoubleField) - (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); - - jmethodID (JNICALL *GetStaticMethodID) - (JNIEnv *env, jclass clazz, const char *name, const char *sig); - - jobject (JNICALL *CallStaticObjectMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jobject (JNICALL *CallStaticObjectMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jobject (JNICALL *CallStaticObjectMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jboolean (JNICALL *CallStaticBooleanMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jboolean (JNICALL *CallStaticBooleanMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jboolean (JNICALL *CallStaticBooleanMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jbyte (JNICALL *CallStaticByteMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jbyte (JNICALL *CallStaticByteMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jbyte (JNICALL *CallStaticByteMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jchar (JNICALL *CallStaticCharMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jchar (JNICALL *CallStaticCharMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jchar (JNICALL *CallStaticCharMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jshort (JNICALL *CallStaticShortMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jshort (JNICALL *CallStaticShortMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jshort (JNICALL *CallStaticShortMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jint (JNICALL *CallStaticIntMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jint (JNICALL *CallStaticIntMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jint (JNICALL *CallStaticIntMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jlong (JNICALL *CallStaticLongMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jlong (JNICALL *CallStaticLongMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jlong (JNICALL *CallStaticLongMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jfloat (JNICALL *CallStaticFloatMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jfloat (JNICALL *CallStaticFloatMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jfloat (JNICALL *CallStaticFloatMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - jdouble (JNICALL *CallStaticDoubleMethod) - (JNIEnv *env, jclass clazz, jmethodID methodID, ...); - jdouble (JNICALL *CallStaticDoubleMethodV) - (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); - jdouble (JNICALL *CallStaticDoubleMethodA) - (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); - - void (JNICALL *CallStaticVoidMethod) - (JNIEnv *env, jclass cls, jmethodID methodID, ...); - void (JNICALL *CallStaticVoidMethodV) - (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); - void (JNICALL *CallStaticVoidMethodA) - (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); - - jfieldID (JNICALL *GetStaticFieldID) - (JNIEnv *env, jclass clazz, const char *name, const char *sig); - jobject (JNICALL *GetStaticObjectField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - jboolean (JNICALL *GetStaticBooleanField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - jbyte (JNICALL *GetStaticByteField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - jchar (JNICALL *GetStaticCharField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - jshort (JNICALL *GetStaticShortField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - jint (JNICALL *GetStaticIntField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - jlong (JNICALL *GetStaticLongField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - jfloat (JNICALL *GetStaticFloatField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - jdouble (JNICALL *GetStaticDoubleField) - (JNIEnv *env, jclass clazz, jfieldID fieldID); - - void (JNICALL *SetStaticObjectField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); - void (JNICALL *SetStaticBooleanField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); - void (JNICALL *SetStaticByteField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); - void (JNICALL *SetStaticCharField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); - void (JNICALL *SetStaticShortField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); - void (JNICALL *SetStaticIntField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); - void (JNICALL *SetStaticLongField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); - void (JNICALL *SetStaticFloatField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); - void (JNICALL *SetStaticDoubleField) - (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); - - jstring (JNICALL *NewString) - (JNIEnv *env, const jchar *unicode, jsize len); - jsize (JNICALL *GetStringLength) - (JNIEnv *env, jstring str); - const jchar *(JNICALL *GetStringChars) - (JNIEnv *env, jstring str, jboolean *isCopy); - void (JNICALL *ReleaseStringChars) - (JNIEnv *env, jstring str, const jchar *chars); - - jstring (JNICALL *NewStringUTF) - (JNIEnv *env, const char *utf); - jsize (JNICALL *GetStringUTFLength) - (JNIEnv *env, jstring str); - const char* (JNICALL *GetStringUTFChars) - (JNIEnv *env, jstring str, jboolean *isCopy); - void (JNICALL *ReleaseStringUTFChars) - (JNIEnv *env, jstring str, const char* chars); - - - jsize (JNICALL *GetArrayLength) - (JNIEnv *env, jarray array); - - jobjectArray (JNICALL *NewObjectArray) - (JNIEnv *env, jsize len, jclass clazz, jobject init); - jobject (JNICALL *GetObjectArrayElement) - (JNIEnv *env, jobjectArray array, jsize index); - void (JNICALL *SetObjectArrayElement) - (JNIEnv *env, jobjectArray array, jsize index, jobject val); - - jbooleanArray (JNICALL *NewBooleanArray) - (JNIEnv *env, jsize len); - jbyteArray (JNICALL *NewByteArray) - (JNIEnv *env, jsize len); - jcharArray (JNICALL *NewCharArray) - (JNIEnv *env, jsize len); - jshortArray (JNICALL *NewShortArray) - (JNIEnv *env, jsize len); - jintArray (JNICALL *NewIntArray) - (JNIEnv *env, jsize len); - jlongArray (JNICALL *NewLongArray) - (JNIEnv *env, jsize len); - jfloatArray (JNICALL *NewFloatArray) - (JNIEnv *env, jsize len); - jdoubleArray (JNICALL *NewDoubleArray) - (JNIEnv *env, jsize len); - - jboolean * (JNICALL *GetBooleanArrayElements) - (JNIEnv *env, jbooleanArray array, jboolean *isCopy); - jbyte * (JNICALL *GetByteArrayElements) - (JNIEnv *env, jbyteArray array, jboolean *isCopy); - jchar * (JNICALL *GetCharArrayElements) - (JNIEnv *env, jcharArray array, jboolean *isCopy); - jshort * (JNICALL *GetShortArrayElements) - (JNIEnv *env, jshortArray array, jboolean *isCopy); - jint * (JNICALL *GetIntArrayElements) - (JNIEnv *env, jintArray array, jboolean *isCopy); - jlong * (JNICALL *GetLongArrayElements) - (JNIEnv *env, jlongArray array, jboolean *isCopy); - jfloat * (JNICALL *GetFloatArrayElements) - (JNIEnv *env, jfloatArray array, jboolean *isCopy); - jdouble * (JNICALL *GetDoubleArrayElements) - (JNIEnv *env, jdoubleArray array, jboolean *isCopy); - - void (JNICALL *ReleaseBooleanArrayElements) - (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); - void (JNICALL *ReleaseByteArrayElements) - (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); - void (JNICALL *ReleaseCharArrayElements) - (JNIEnv *env, jcharArray array, jchar *elems, jint mode); - void (JNICALL *ReleaseShortArrayElements) - (JNIEnv *env, jshortArray array, jshort *elems, jint mode); - void (JNICALL *ReleaseIntArrayElements) - (JNIEnv *env, jintArray array, jint *elems, jint mode); - void (JNICALL *ReleaseLongArrayElements) - (JNIEnv *env, jlongArray array, jlong *elems, jint mode); - void (JNICALL *ReleaseFloatArrayElements) - (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); - void (JNICALL *ReleaseDoubleArrayElements) - (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); - - void (JNICALL *GetBooleanArrayRegion) - (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); - void (JNICALL *GetByteArrayRegion) - (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); - void (JNICALL *GetCharArrayRegion) - (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); - void (JNICALL *GetShortArrayRegion) - (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); - void (JNICALL *GetIntArrayRegion) - (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); - void (JNICALL *GetLongArrayRegion) - (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); - void (JNICALL *GetFloatArrayRegion) - (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); - void (JNICALL *GetDoubleArrayRegion) - (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); - - void (JNICALL *SetBooleanArrayRegion) - (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); - void (JNICALL *SetByteArrayRegion) - (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); - void (JNICALL *SetCharArrayRegion) - (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); - void (JNICALL *SetShortArrayRegion) - (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); - void (JNICALL *SetIntArrayRegion) - (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); - void (JNICALL *SetLongArrayRegion) - (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); - void (JNICALL *SetFloatArrayRegion) - (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); - void (JNICALL *SetDoubleArrayRegion) - (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); - - jint (JNICALL *RegisterNatives) - (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, - jint nMethods); - jint (JNICALL *UnregisterNatives) - (JNIEnv *env, jclass clazz); - - jint (JNICALL *MonitorEnter) - (JNIEnv *env, jobject obj); - jint (JNICALL *MonitorExit) - (JNIEnv *env, jobject obj); - - jint (JNICALL *GetJavaVM) - (JNIEnv *env, JavaVM **vm); - - void (JNICALL *GetStringRegion) - (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); - void (JNICALL *GetStringUTFRegion) - (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); - - void * (JNICALL *GetPrimitiveArrayCritical) - (JNIEnv *env, jarray array, jboolean *isCopy); - void (JNICALL *ReleasePrimitiveArrayCritical) - (JNIEnv *env, jarray array, void *carray, jint mode); - - const jchar * (JNICALL *GetStringCritical) - (JNIEnv *env, jstring string, jboolean *isCopy); - void (JNICALL *ReleaseStringCritical) - (JNIEnv *env, jstring string, const jchar *cstring); - - jweak (JNICALL *NewWeakGlobalRef) - (JNIEnv *env, jobject obj); - void (JNICALL *DeleteWeakGlobalRef) - (JNIEnv *env, jweak ref); - - jboolean (JNICALL *ExceptionCheck) - (JNIEnv *env); - - jobject (JNICALL *NewDirectByteBuffer) - (JNIEnv* env, void* address, jlong capacity); - void* (JNICALL *GetDirectBufferAddress) - (JNIEnv* env, jobject buf); - jlong (JNICALL *GetDirectBufferCapacity) - (JNIEnv* env, jobject buf); - - /* New JNI 1.6 Features */ - - jobjectRefType (JNICALL *GetObjectRefType) - (JNIEnv* env, jobject obj); -}; - -/* - * We use inlined functions for C++ so that programmers can write: - * - * env->FindClass("java/lang/String") - * - * in C++ rather than: - * - * (*env)->FindClass(env, "java/lang/String") - * - * in C. - */ - -struct JNIEnv_ { - const struct JNINativeInterface_ *functions; -#ifdef __cplusplus - - jint GetVersion() { - return functions->GetVersion(this); - } - jclass DefineClass(const char *name, jobject loader, const jbyte *buf, - jsize len) { - return functions->DefineClass(this, name, loader, buf, len); - } - jclass FindClass(const char *name) { - return functions->FindClass(this, name); - } - jmethodID FromReflectedMethod(jobject method) { - return functions->FromReflectedMethod(this,method); - } - jfieldID FromReflectedField(jobject field) { - return functions->FromReflectedField(this,field); - } - - jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { - return functions->ToReflectedMethod(this, cls, methodID, isStatic); - } - - jclass GetSuperclass(jclass sub) { - return functions->GetSuperclass(this, sub); - } - jboolean IsAssignableFrom(jclass sub, jclass sup) { - return functions->IsAssignableFrom(this, sub, sup); - } - - jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { - return functions->ToReflectedField(this,cls,fieldID,isStatic); - } - - jint Throw(jthrowable obj) { - return functions->Throw(this, obj); - } - jint ThrowNew(jclass clazz, const char *msg) { - return functions->ThrowNew(this, clazz, msg); - } - jthrowable ExceptionOccurred() { - return functions->ExceptionOccurred(this); - } - void ExceptionDescribe() { - functions->ExceptionDescribe(this); - } - void ExceptionClear() { - functions->ExceptionClear(this); - } - void FatalError(const char *msg) { - functions->FatalError(this, msg); - } - - jint PushLocalFrame(jint capacity) { - return functions->PushLocalFrame(this,capacity); - } - jobject PopLocalFrame(jobject result) { - return functions->PopLocalFrame(this,result); - } - - jobject NewGlobalRef(jobject lobj) { - return functions->NewGlobalRef(this,lobj); - } - void DeleteGlobalRef(jobject gref) { - functions->DeleteGlobalRef(this,gref); - } - void DeleteLocalRef(jobject obj) { - functions->DeleteLocalRef(this, obj); - } - - jboolean IsSameObject(jobject obj1, jobject obj2) { - return functions->IsSameObject(this,obj1,obj2); - } - - jobject NewLocalRef(jobject ref) { - return functions->NewLocalRef(this,ref); - } - jint EnsureLocalCapacity(jint capacity) { - return functions->EnsureLocalCapacity(this,capacity); - } - - jobject AllocObject(jclass clazz) { - return functions->AllocObject(this,clazz); - } - jobject NewObject(jclass clazz, jmethodID methodID, ...) { - va_list args; - jobject result; - va_start(args, methodID); - result = functions->NewObjectV(this,clazz,methodID,args); - va_end(args); - return result; - } - jobject NewObjectV(jclass clazz, jmethodID methodID, - va_list args) { - return functions->NewObjectV(this,clazz,methodID,args); - } - jobject NewObjectA(jclass clazz, jmethodID methodID, - const jvalue *args) { - return functions->NewObjectA(this,clazz,methodID,args); - } - - jclass GetObjectClass(jobject obj) { - return functions->GetObjectClass(this,obj); - } - jboolean IsInstanceOf(jobject obj, jclass clazz) { - return functions->IsInstanceOf(this,obj,clazz); - } - - jmethodID GetMethodID(jclass clazz, const char *name, - const char *sig) { - return functions->GetMethodID(this,clazz,name,sig); - } - - jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - jobject result; - va_start(args,methodID); - result = functions->CallObjectMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jobject CallObjectMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallObjectMethodV(this,obj,methodID,args); - } - jobject CallObjectMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallObjectMethodA(this,obj,methodID,args); - } - - jboolean CallBooleanMethod(jobject obj, - jmethodID methodID, ...) { - va_list args; - jboolean result; - va_start(args,methodID); - result = functions->CallBooleanMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallBooleanMethodV(this,obj,methodID,args); - } - jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallBooleanMethodA(this,obj,methodID, args); - } - - jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - jbyte result; - va_start(args,methodID); - result = functions->CallByteMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jbyte CallByteMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallByteMethodV(this,obj,methodID,args); - } - jbyte CallByteMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallByteMethodA(this,obj,methodID,args); - } - - jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - jchar result; - va_start(args,methodID); - result = functions->CallCharMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jchar CallCharMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallCharMethodV(this,obj,methodID,args); - } - jchar CallCharMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallCharMethodA(this,obj,methodID,args); - } - - jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - jshort result; - va_start(args,methodID); - result = functions->CallShortMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jshort CallShortMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallShortMethodV(this,obj,methodID,args); - } - jshort CallShortMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallShortMethodA(this,obj,methodID,args); - } - - jint CallIntMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - jint result; - va_start(args,methodID); - result = functions->CallIntMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jint CallIntMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallIntMethodV(this,obj,methodID,args); - } - jint CallIntMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallIntMethodA(this,obj,methodID,args); - } - - jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - jlong result; - va_start(args,methodID); - result = functions->CallLongMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jlong CallLongMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallLongMethodV(this,obj,methodID,args); - } - jlong CallLongMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallLongMethodA(this,obj,methodID,args); - } - - jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - jfloat result; - va_start(args,methodID); - result = functions->CallFloatMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jfloat CallFloatMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallFloatMethodV(this,obj,methodID,args); - } - jfloat CallFloatMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallFloatMethodA(this,obj,methodID,args); - } - - jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - jdouble result; - va_start(args,methodID); - result = functions->CallDoubleMethodV(this,obj,methodID,args); - va_end(args); - return result; - } - jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, - va_list args) { - return functions->CallDoubleMethodV(this,obj,methodID,args); - } - jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - return functions->CallDoubleMethodA(this,obj,methodID,args); - } - - void CallVoidMethod(jobject obj, jmethodID methodID, ...) { - va_list args; - va_start(args,methodID); - functions->CallVoidMethodV(this,obj,methodID,args); - va_end(args); - } - void CallVoidMethodV(jobject obj, jmethodID methodID, - va_list args) { - functions->CallVoidMethodV(this,obj,methodID,args); - } - void CallVoidMethodA(jobject obj, jmethodID methodID, - const jvalue * args) { - functions->CallVoidMethodA(this,obj,methodID,args); - } - - jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jobject result; - va_start(args,methodID); - result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallNonvirtualObjectMethodV(this,obj,clazz, - methodID,args); - } - jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, - jmethodID methodID, const jvalue * args) { - return functions->CallNonvirtualObjectMethodA(this,obj,clazz, - methodID,args); - } - - jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jboolean result; - va_start(args,methodID); - result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, - methodID,args); - } - jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, - jmethodID methodID, const jvalue * args) { - return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, - methodID, args); - } - - jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jbyte result; - va_start(args,methodID); - result = functions->CallNonvirtualByteMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallNonvirtualByteMethodV(this,obj,clazz, - methodID,args); - } - jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, - jmethodID methodID, const jvalue * args) { - return functions->CallNonvirtualByteMethodA(this,obj,clazz, - methodID,args); - } - - jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jchar result; - va_start(args,methodID); - result = functions->CallNonvirtualCharMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallNonvirtualCharMethodV(this,obj,clazz, - methodID,args); - } - jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, - jmethodID methodID, const jvalue * args) { - return functions->CallNonvirtualCharMethodA(this,obj,clazz, - methodID,args); - } - - jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jshort result; - va_start(args,methodID); - result = functions->CallNonvirtualShortMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallNonvirtualShortMethodV(this,obj,clazz, - methodID,args); - } - jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, - jmethodID methodID, const jvalue * args) { - return functions->CallNonvirtualShortMethodA(this,obj,clazz, - methodID,args); - } - - jint CallNonvirtualIntMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jint result; - va_start(args,methodID); - result = functions->CallNonvirtualIntMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallNonvirtualIntMethodV(this,obj,clazz, - methodID,args); - } - jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, - jmethodID methodID, const jvalue * args) { - return functions->CallNonvirtualIntMethodA(this,obj,clazz, - methodID,args); - } - - jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jlong result; - va_start(args,methodID); - result = functions->CallNonvirtualLongMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallNonvirtualLongMethodV(this,obj,clazz, - methodID,args); - } - jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, - jmethodID methodID, const jvalue * args) { - return functions->CallNonvirtualLongMethodA(this,obj,clazz, - methodID,args); - } - - jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jfloat result; - va_start(args,methodID); - result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, - jmethodID methodID, - va_list args) { - return functions->CallNonvirtualFloatMethodV(this,obj,clazz, - methodID,args); - } - jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, - jmethodID methodID, - const jvalue * args) { - return functions->CallNonvirtualFloatMethodA(this,obj,clazz, - methodID,args); - } - - jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - jdouble result; - va_start(args,methodID); - result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, - methodID,args); - va_end(args); - return result; - } - jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, - jmethodID methodID, - va_list args) { - return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, - methodID,args); - } - jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, - jmethodID methodID, - const jvalue * args) { - return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, - methodID,args); - } - - void CallNonvirtualVoidMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) { - va_list args; - va_start(args,methodID); - functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); - va_end(args); - } - void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, - jmethodID methodID, - va_list args) { - functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); - } - void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, - jmethodID methodID, - const jvalue * args) { - functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); - } - - jfieldID GetFieldID(jclass clazz, const char *name, - const char *sig) { - return functions->GetFieldID(this,clazz,name,sig); - } - - jobject GetObjectField(jobject obj, jfieldID fieldID) { - return functions->GetObjectField(this,obj,fieldID); - } - jboolean GetBooleanField(jobject obj, jfieldID fieldID) { - return functions->GetBooleanField(this,obj,fieldID); - } - jbyte GetByteField(jobject obj, jfieldID fieldID) { - return functions->GetByteField(this,obj,fieldID); - } - jchar GetCharField(jobject obj, jfieldID fieldID) { - return functions->GetCharField(this,obj,fieldID); - } - jshort GetShortField(jobject obj, jfieldID fieldID) { - return functions->GetShortField(this,obj,fieldID); - } - jint GetIntField(jobject obj, jfieldID fieldID) { - return functions->GetIntField(this,obj,fieldID); - } - jlong GetLongField(jobject obj, jfieldID fieldID) { - return functions->GetLongField(this,obj,fieldID); - } - jfloat GetFloatField(jobject obj, jfieldID fieldID) { - return functions->GetFloatField(this,obj,fieldID); - } - jdouble GetDoubleField(jobject obj, jfieldID fieldID) { - return functions->GetDoubleField(this,obj,fieldID); - } - - void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { - functions->SetObjectField(this,obj,fieldID,val); - } - void SetBooleanField(jobject obj, jfieldID fieldID, - jboolean val) { - functions->SetBooleanField(this,obj,fieldID,val); - } - void SetByteField(jobject obj, jfieldID fieldID, - jbyte val) { - functions->SetByteField(this,obj,fieldID,val); - } - void SetCharField(jobject obj, jfieldID fieldID, - jchar val) { - functions->SetCharField(this,obj,fieldID,val); - } - void SetShortField(jobject obj, jfieldID fieldID, - jshort val) { - functions->SetShortField(this,obj,fieldID,val); - } - void SetIntField(jobject obj, jfieldID fieldID, - jint val) { - functions->SetIntField(this,obj,fieldID,val); - } - void SetLongField(jobject obj, jfieldID fieldID, - jlong val) { - functions->SetLongField(this,obj,fieldID,val); - } - void SetFloatField(jobject obj, jfieldID fieldID, - jfloat val) { - functions->SetFloatField(this,obj,fieldID,val); - } - void SetDoubleField(jobject obj, jfieldID fieldID, - jdouble val) { - functions->SetDoubleField(this,obj,fieldID,val); - } - - jmethodID GetStaticMethodID(jclass clazz, const char *name, - const char *sig) { - return functions->GetStaticMethodID(this,clazz,name,sig); - } - - jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, - ...) { - va_list args; - jobject result; - va_start(args,methodID); - result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, - va_list args) { - return functions->CallStaticObjectMethodV(this,clazz,methodID,args); - } - jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, - const jvalue *args) { - return functions->CallStaticObjectMethodA(this,clazz,methodID,args); - } - - jboolean CallStaticBooleanMethod(jclass clazz, - jmethodID methodID, ...) { - va_list args; - jboolean result; - va_start(args,methodID); - result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jboolean CallStaticBooleanMethodV(jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); - } - jboolean CallStaticBooleanMethodA(jclass clazz, - jmethodID methodID, const jvalue *args) { - return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); - } - - jbyte CallStaticByteMethod(jclass clazz, - jmethodID methodID, ...) { - va_list args; - jbyte result; - va_start(args,methodID); - result = functions->CallStaticByteMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jbyte CallStaticByteMethodV(jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallStaticByteMethodV(this,clazz,methodID,args); - } - jbyte CallStaticByteMethodA(jclass clazz, - jmethodID methodID, const jvalue *args) { - return functions->CallStaticByteMethodA(this,clazz,methodID,args); - } - - jchar CallStaticCharMethod(jclass clazz, - jmethodID methodID, ...) { - va_list args; - jchar result; - va_start(args,methodID); - result = functions->CallStaticCharMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jchar CallStaticCharMethodV(jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallStaticCharMethodV(this,clazz,methodID,args); - } - jchar CallStaticCharMethodA(jclass clazz, - jmethodID methodID, const jvalue *args) { - return functions->CallStaticCharMethodA(this,clazz,methodID,args); - } - - jshort CallStaticShortMethod(jclass clazz, - jmethodID methodID, ...) { - va_list args; - jshort result; - va_start(args,methodID); - result = functions->CallStaticShortMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jshort CallStaticShortMethodV(jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallStaticShortMethodV(this,clazz,methodID,args); - } - jshort CallStaticShortMethodA(jclass clazz, - jmethodID methodID, const jvalue *args) { - return functions->CallStaticShortMethodA(this,clazz,methodID,args); - } - - jint CallStaticIntMethod(jclass clazz, - jmethodID methodID, ...) { - va_list args; - jint result; - va_start(args,methodID); - result = functions->CallStaticIntMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jint CallStaticIntMethodV(jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallStaticIntMethodV(this,clazz,methodID,args); - } - jint CallStaticIntMethodA(jclass clazz, - jmethodID methodID, const jvalue *args) { - return functions->CallStaticIntMethodA(this,clazz,methodID,args); - } - - jlong CallStaticLongMethod(jclass clazz, - jmethodID methodID, ...) { - va_list args; - jlong result; - va_start(args,methodID); - result = functions->CallStaticLongMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jlong CallStaticLongMethodV(jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallStaticLongMethodV(this,clazz,methodID,args); - } - jlong CallStaticLongMethodA(jclass clazz, - jmethodID methodID, const jvalue *args) { - return functions->CallStaticLongMethodA(this,clazz,methodID,args); - } - - jfloat CallStaticFloatMethod(jclass clazz, - jmethodID methodID, ...) { - va_list args; - jfloat result; - va_start(args,methodID); - result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jfloat CallStaticFloatMethodV(jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallStaticFloatMethodV(this,clazz,methodID,args); - } - jfloat CallStaticFloatMethodA(jclass clazz, - jmethodID methodID, const jvalue *args) { - return functions->CallStaticFloatMethodA(this,clazz,methodID,args); - } - - jdouble CallStaticDoubleMethod(jclass clazz, - jmethodID methodID, ...) { - va_list args; - jdouble result; - va_start(args,methodID); - result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); - va_end(args); - return result; - } - jdouble CallStaticDoubleMethodV(jclass clazz, - jmethodID methodID, va_list args) { - return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); - } - jdouble CallStaticDoubleMethodA(jclass clazz, - jmethodID methodID, const jvalue *args) { - return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); - } - - void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { - va_list args; - va_start(args,methodID); - functions->CallStaticVoidMethodV(this,cls,methodID,args); - va_end(args); - } - void CallStaticVoidMethodV(jclass cls, jmethodID methodID, - va_list args) { - functions->CallStaticVoidMethodV(this,cls,methodID,args); - } - void CallStaticVoidMethodA(jclass cls, jmethodID methodID, - const jvalue * args) { - functions->CallStaticVoidMethodA(this,cls,methodID,args); - } - - jfieldID GetStaticFieldID(jclass clazz, const char *name, - const char *sig) { - return functions->GetStaticFieldID(this,clazz,name,sig); - } - jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticObjectField(this,clazz,fieldID); - } - jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticBooleanField(this,clazz,fieldID); - } - jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticByteField(this,clazz,fieldID); - } - jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticCharField(this,clazz,fieldID); - } - jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticShortField(this,clazz,fieldID); - } - jint GetStaticIntField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticIntField(this,clazz,fieldID); - } - jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticLongField(this,clazz,fieldID); - } - jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticFloatField(this,clazz,fieldID); - } - jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { - return functions->GetStaticDoubleField(this,clazz,fieldID); - } - - void SetStaticObjectField(jclass clazz, jfieldID fieldID, - jobject value) { - functions->SetStaticObjectField(this,clazz,fieldID,value); - } - void SetStaticBooleanField(jclass clazz, jfieldID fieldID, - jboolean value) { - functions->SetStaticBooleanField(this,clazz,fieldID,value); - } - void SetStaticByteField(jclass clazz, jfieldID fieldID, - jbyte value) { - functions->SetStaticByteField(this,clazz,fieldID,value); - } - void SetStaticCharField(jclass clazz, jfieldID fieldID, - jchar value) { - functions->SetStaticCharField(this,clazz,fieldID,value); - } - void SetStaticShortField(jclass clazz, jfieldID fieldID, - jshort value) { - functions->SetStaticShortField(this,clazz,fieldID,value); - } - void SetStaticIntField(jclass clazz, jfieldID fieldID, - jint value) { - functions->SetStaticIntField(this,clazz,fieldID,value); - } - void SetStaticLongField(jclass clazz, jfieldID fieldID, - jlong value) { - functions->SetStaticLongField(this,clazz,fieldID,value); - } - void SetStaticFloatField(jclass clazz, jfieldID fieldID, - jfloat value) { - functions->SetStaticFloatField(this,clazz,fieldID,value); - } - void SetStaticDoubleField(jclass clazz, jfieldID fieldID, - jdouble value) { - functions->SetStaticDoubleField(this,clazz,fieldID,value); - } - - jstring NewString(const jchar *unicode, jsize len) { - return functions->NewString(this,unicode,len); - } - jsize GetStringLength(jstring str) { - return functions->GetStringLength(this,str); - } - const jchar *GetStringChars(jstring str, jboolean *isCopy) { - return functions->GetStringChars(this,str,isCopy); - } - void ReleaseStringChars(jstring str, const jchar *chars) { - functions->ReleaseStringChars(this,str,chars); - } - - jstring NewStringUTF(const char *utf) { - return functions->NewStringUTF(this,utf); - } - jsize GetStringUTFLength(jstring str) { - return functions->GetStringUTFLength(this,str); - } - const char* GetStringUTFChars(jstring str, jboolean *isCopy) { - return functions->GetStringUTFChars(this,str,isCopy); - } - void ReleaseStringUTFChars(jstring str, const char* chars) { - functions->ReleaseStringUTFChars(this,str,chars); - } - - jsize GetArrayLength(jarray array) { - return functions->GetArrayLength(this,array); - } - - jobjectArray NewObjectArray(jsize len, jclass clazz, - jobject init) { - return functions->NewObjectArray(this,len,clazz,init); - } - jobject GetObjectArrayElement(jobjectArray array, jsize index) { - return functions->GetObjectArrayElement(this,array,index); - } - void SetObjectArrayElement(jobjectArray array, jsize index, - jobject val) { - functions->SetObjectArrayElement(this,array,index,val); - } - - jbooleanArray NewBooleanArray(jsize len) { - return functions->NewBooleanArray(this,len); - } - jbyteArray NewByteArray(jsize len) { - return functions->NewByteArray(this,len); - } - jcharArray NewCharArray(jsize len) { - return functions->NewCharArray(this,len); - } - jshortArray NewShortArray(jsize len) { - return functions->NewShortArray(this,len); - } - jintArray NewIntArray(jsize len) { - return functions->NewIntArray(this,len); - } - jlongArray NewLongArray(jsize len) { - return functions->NewLongArray(this,len); - } - jfloatArray NewFloatArray(jsize len) { - return functions->NewFloatArray(this,len); - } - jdoubleArray NewDoubleArray(jsize len) { - return functions->NewDoubleArray(this,len); - } - - jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { - return functions->GetBooleanArrayElements(this,array,isCopy); - } - jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { - return functions->GetByteArrayElements(this,array,isCopy); - } - jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { - return functions->GetCharArrayElements(this,array,isCopy); - } - jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { - return functions->GetShortArrayElements(this,array,isCopy); - } - jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { - return functions->GetIntArrayElements(this,array,isCopy); - } - jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { - return functions->GetLongArrayElements(this,array,isCopy); - } - jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { - return functions->GetFloatArrayElements(this,array,isCopy); - } - jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { - return functions->GetDoubleArrayElements(this,array,isCopy); - } - - void ReleaseBooleanArrayElements(jbooleanArray array, - jboolean *elems, - jint mode) { - functions->ReleaseBooleanArrayElements(this,array,elems,mode); - } - void ReleaseByteArrayElements(jbyteArray array, - jbyte *elems, - jint mode) { - functions->ReleaseByteArrayElements(this,array,elems,mode); - } - void ReleaseCharArrayElements(jcharArray array, - jchar *elems, - jint mode) { - functions->ReleaseCharArrayElements(this,array,elems,mode); - } - void ReleaseShortArrayElements(jshortArray array, - jshort *elems, - jint mode) { - functions->ReleaseShortArrayElements(this,array,elems,mode); - } - void ReleaseIntArrayElements(jintArray array, - jint *elems, - jint mode) { - functions->ReleaseIntArrayElements(this,array,elems,mode); - } - void ReleaseLongArrayElements(jlongArray array, - jlong *elems, - jint mode) { - functions->ReleaseLongArrayElements(this,array,elems,mode); - } - void ReleaseFloatArrayElements(jfloatArray array, - jfloat *elems, - jint mode) { - functions->ReleaseFloatArrayElements(this,array,elems,mode); - } - void ReleaseDoubleArrayElements(jdoubleArray array, - jdouble *elems, - jint mode) { - functions->ReleaseDoubleArrayElements(this,array,elems,mode); - } - - void GetBooleanArrayRegion(jbooleanArray array, - jsize start, jsize len, jboolean *buf) { - functions->GetBooleanArrayRegion(this,array,start,len,buf); - } - void GetByteArrayRegion(jbyteArray array, - jsize start, jsize len, jbyte *buf) { - functions->GetByteArrayRegion(this,array,start,len,buf); - } - void GetCharArrayRegion(jcharArray array, - jsize start, jsize len, jchar *buf) { - functions->GetCharArrayRegion(this,array,start,len,buf); - } - void GetShortArrayRegion(jshortArray array, - jsize start, jsize len, jshort *buf) { - functions->GetShortArrayRegion(this,array,start,len,buf); - } - void GetIntArrayRegion(jintArray array, - jsize start, jsize len, jint *buf) { - functions->GetIntArrayRegion(this,array,start,len,buf); - } - void GetLongArrayRegion(jlongArray array, - jsize start, jsize len, jlong *buf) { - functions->GetLongArrayRegion(this,array,start,len,buf); - } - void GetFloatArrayRegion(jfloatArray array, - jsize start, jsize len, jfloat *buf) { - functions->GetFloatArrayRegion(this,array,start,len,buf); - } - void GetDoubleArrayRegion(jdoubleArray array, - jsize start, jsize len, jdouble *buf) { - functions->GetDoubleArrayRegion(this,array,start,len,buf); - } - - void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, - const jboolean *buf) { - functions->SetBooleanArrayRegion(this,array,start,len,buf); - } - void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, - const jbyte *buf) { - functions->SetByteArrayRegion(this,array,start,len,buf); - } - void SetCharArrayRegion(jcharArray array, jsize start, jsize len, - const jchar *buf) { - functions->SetCharArrayRegion(this,array,start,len,buf); - } - void SetShortArrayRegion(jshortArray array, jsize start, jsize len, - const jshort *buf) { - functions->SetShortArrayRegion(this,array,start,len,buf); - } - void SetIntArrayRegion(jintArray array, jsize start, jsize len, - const jint *buf) { - functions->SetIntArrayRegion(this,array,start,len,buf); - } - void SetLongArrayRegion(jlongArray array, jsize start, jsize len, - const jlong *buf) { - functions->SetLongArrayRegion(this,array,start,len,buf); - } - void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, - const jfloat *buf) { - functions->SetFloatArrayRegion(this,array,start,len,buf); - } - void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, - const jdouble *buf) { - functions->SetDoubleArrayRegion(this,array,start,len,buf); - } - - jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, - jint nMethods) { - return functions->RegisterNatives(this,clazz,methods,nMethods); - } - jint UnregisterNatives(jclass clazz) { - return functions->UnregisterNatives(this,clazz); - } - - jint MonitorEnter(jobject obj) { - return functions->MonitorEnter(this,obj); - } - jint MonitorExit(jobject obj) { - return functions->MonitorExit(this,obj); - } - - jint GetJavaVM(JavaVM **vm) { - return functions->GetJavaVM(this,vm); - } - - void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { - functions->GetStringRegion(this,str,start,len,buf); - } - void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { - functions->GetStringUTFRegion(this,str,start,len,buf); - } - - void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { - return functions->GetPrimitiveArrayCritical(this,array,isCopy); - } - void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { - functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); - } - - const jchar * GetStringCritical(jstring string, jboolean *isCopy) { - return functions->GetStringCritical(this,string,isCopy); - } - void ReleaseStringCritical(jstring string, const jchar *cstring) { - functions->ReleaseStringCritical(this,string,cstring); - } - - jweak NewWeakGlobalRef(jobject obj) { - return functions->NewWeakGlobalRef(this,obj); - } - void DeleteWeakGlobalRef(jweak ref) { - functions->DeleteWeakGlobalRef(this,ref); - } - - jboolean ExceptionCheck() { - return functions->ExceptionCheck(this); - } - - jobject NewDirectByteBuffer(void* address, jlong capacity) { - return functions->NewDirectByteBuffer(this, address, capacity); - } - void* GetDirectBufferAddress(jobject buf) { - return functions->GetDirectBufferAddress(this, buf); - } - jlong GetDirectBufferCapacity(jobject buf) { - return functions->GetDirectBufferCapacity(this, buf); - } - jobjectRefType GetObjectRefType(jobject obj) { - return functions->GetObjectRefType(this, obj); - } - -#endif /* __cplusplus */ -}; - -typedef struct JavaVMOption { - char *optionString; - void *extraInfo; -} JavaVMOption; - -typedef struct JavaVMInitArgs { - jint version; - - jint nOptions; - JavaVMOption *options; - jboolean ignoreUnrecognized; -} JavaVMInitArgs; - -typedef struct JavaVMAttachArgs { - jint version; - - char *name; - jobject group; -} JavaVMAttachArgs; - -/* These will be VM-specific. */ - -#define JDK1_2 -#define JDK1_4 - -/* End VM-specific. */ - -struct JNIInvokeInterface_ { - void *reserved0; - void *reserved1; - void *reserved2; - - jint (JNICALL *DestroyJavaVM)(JavaVM *vm); - - jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); - - jint (JNICALL *DetachCurrentThread)(JavaVM *vm); - - jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); - - jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); -}; - -struct JavaVM_ { - const struct JNIInvokeInterface_ *functions; -#ifdef __cplusplus - - jint DestroyJavaVM() { - return functions->DestroyJavaVM(this); - } - jint AttachCurrentThread(void **penv, void *args) { - return functions->AttachCurrentThread(this, penv, args); - } - jint DetachCurrentThread() { - return functions->DetachCurrentThread(this); - } - - jint GetEnv(void **penv, jint version) { - return functions->GetEnv(this, penv, version); - } - jint AttachCurrentThreadAsDaemon(void **penv, void *args) { - return functions->AttachCurrentThreadAsDaemon(this, penv, args); - } -#endif -}; - -#ifdef _JNI_IMPLEMENTATION_ -#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT -#else -#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT -#endif -_JNI_IMPORT_OR_EXPORT_ jint JNICALL -JNI_GetDefaultJavaVMInitArgs(void *args); - -_JNI_IMPORT_OR_EXPORT_ jint JNICALL -JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); - -_JNI_IMPORT_OR_EXPORT_ jint JNICALL -JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); - -/* Defined by native libraries. */ -JNIEXPORT jint JNICALL -JNI_OnLoad(JavaVM *vm, void *reserved); - -JNIEXPORT void JNICALL -JNI_OnUnload(JavaVM *vm, void *reserved); - -#define JNI_VERSION_1_1 0x00010001 -#define JNI_VERSION_1_2 0x00010002 -#define JNI_VERSION_1_4 0x00010004 -#define JNI_VERSION_1_6 0x00010006 - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* !_JAVASOFT_JNI_H_ */ - - - diff --git a/native/IdeaWin32/jni_md.h b/native/IdeaWin32/jni_md.h deleted file mode 100644 index 9f0cfa463837..000000000000 --- a/native/IdeaWin32/jni_md.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * @(#)jni_md.h 1.15 05/11/17 - * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -#ifndef _JAVASOFT_JNI_MD_H_ -#define _JAVASOFT_JNI_MD_H_ - -#define JNIEXPORT __declspec(dllexport) -#define JNIIMPORT __declspec(dllimport) -#define JNICALL __stdcall - -typedef long jint; -typedef __int64 jlong; -typedef signed char jbyte; - -#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/native/IdeaWin32/jni_util.h b/native/IdeaWin32/jni_util.h deleted file mode 100644 index a1ae06ad4447..000000000000 --- a/native/IdeaWin32/jni_util.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -#ifndef JNI_UTIL_H -#define JNI_UTIL_H - -#include "jni.h" -#include "jlong.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This file contains utility functions that can be implemented in pure JNI. - * - * Caution: Callers of functions declared in this file should be - * particularly aware of the fact that these functions are convenience - * functions, and as such are often compound operations, each one of - * which may throw an exception. Therefore, the functions this file - * will often return silently if an exception has occured, and callers - * must check for exception themselves. - */ - -/* Throw a Java exception by name. Similar to SignalError. */ -JNIEXPORT void JNICALL -JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg); - -/* Throw common exceptions */ -JNIEXPORT void JNICALL -JNU_ThrowNullPointerException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowInternalError(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowIOException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg); - -JNIEXPORT void JNICALL -JNU_ThrowInstantiationException(JNIEnv *env, const char *msg); - -/* Throw an exception by name, using the string returned by - * JVM_LastErrorString for the detail string. If the last-error - * string is NULL, use the given default detail string. - */ -JNIEXPORT void JNICALL -JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name, - const char *defaultMessage); - -/* Throw an IOException, using the last-error string for the detail - * string. If the last-error string is NULL, use the given default - * detail string. - */ -JNIEXPORT void JNICALL -JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail); - -/* Convert between Java strings and i18n C strings */ -JNIEXPORT jstring -NewStringPlatform(JNIEnv *env, const char *str); - -JNIEXPORT const char * -GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy); - -JNIEXPORT jstring JNICALL -JNU_NewStringPlatform(JNIEnv *env, const char *str); - -JNIEXPORT const char * JNICALL -JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy); - -JNIEXPORT void JNICALL -JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str); - -/* Class constants */ -JNIEXPORT jclass JNICALL -JNU_ClassString(JNIEnv *env); - -JNIEXPORT jclass JNICALL -JNU_ClassClass(JNIEnv *env); - -JNIEXPORT jclass JNICALL -JNU_ClassObject(JNIEnv *env); - -JNIEXPORT jclass JNICALL -JNU_ClassThrowable(JNIEnv *env); - -/* Copy count number of arguments from src to dst. Array bounds - * and ArrayStoreException are checked. - */ -JNIEXPORT jint JNICALL -JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src, - jint count); - -/* Invoke a object-returning static method, based on class name, - * method name, and signature string. - * - * The caller should check for exceptions by setting hasException - * argument. If the caller is not interested in whether an exception - * has occurred, pass in NULL. - */ -JNIEXPORT jvalue JNICALL -JNU_CallStaticMethodByName(JNIEnv *env, - jboolean *hasException, - const char *class_name, - const char *name, - const char *signature, - ...); - -/* Invoke an instance method by name. - */ -JNIEXPORT jvalue JNICALL -JNU_CallMethodByName(JNIEnv *env, - jboolean *hasException, - jobject obj, - const char *name, - const char *signature, - ...); - -JNIEXPORT jvalue JNICALL -JNU_CallMethodByNameV(JNIEnv *env, - jboolean *hasException, - jobject obj, - const char *name, - const char *signature, - va_list args); - -/* Construct a new object of class, specifying the class by name, - * and specififying which constructor to run and what arguments to - * pass to it. - * - * The method will return an initialized instance if successful. - * It will return NULL if an error has occured (for example if - * it ran out of memory) and the appropriate Java exception will - * have been thrown. - */ -JNIEXPORT jobject JNICALL -JNU_NewObjectByName(JNIEnv *env, const char *class_name, - const char *constructor_sig, ...); - -/* returns: - * 0: object is not an instance of the class named by classname. - * 1: object is an instance of the class named by classname. - * -1: the class named by classname cannot be found. An exception - * has been thrown. - */ -JNIEXPORT jint JNICALL -JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char *classname); - - -/* Get or set class and instance fields. - * Note that set functions take a variable number of arguments, - * but only one argument of the appropriate type can be passed. - * For example, to set an integer field i to 100: - * - * JNU_SetFieldByName(env, &exc, obj, "i", "I", 100); - * - * To set a float field f to 12.3: - * - * JNU_SetFieldByName(env, &exc, obj, "f", "F", 12.3); - * - * The caller should check for exceptions by setting hasException - * argument. If the caller is not interested in whether an exception - * has occurred, pass in NULL. - */ -JNIEXPORT jvalue JNICALL -JNU_GetFieldByName(JNIEnv *env, - jboolean *hasException, - jobject obj, - const char *name, - const char *sig); -JNIEXPORT void JNICALL -JNU_SetFieldByName(JNIEnv *env, - jboolean *hasException, - jobject obj, - const char *name, - const char *sig, - ...); - -JNIEXPORT jvalue JNICALL -JNU_GetStaticFieldByName(JNIEnv *env, - jboolean *hasException, - const char *classname, - const char *name, - const char *sig); -JNIEXPORT void JNICALL -JNU_SetStaticFieldByName(JNIEnv *env, - jboolean *hasException, - const char *classname, - const char *name, - const char *sig, - ...); - - -/* - * Calls the .equals method. - */ -JNIEXPORT jboolean JNICALL -JNU_Equals(JNIEnv *env, jobject object1, jobject object2); - - -/************************************************************************ - * Thread calls - * - * Convenience thread-related calls on the java.lang.Object class. - */ - -JNIEXPORT void JNICALL -JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout); - -JNIEXPORT void JNICALL -JNU_Notify(JNIEnv *env, jobject object); - -JNIEXPORT void JNICALL -JNU_NotifyAll(JNIEnv *env, jobject object); - - -/************************************************************************ - * Miscellaneous utilities used by the class libraries - */ - -#define IS_NULL(obj) ((obj) == NULL) -#define JNU_IsNull(env,obj) ((obj) == NULL) - - -/************************************************************************ - * Debugging utilities - */ - -JNIEXPORT void JNICALL -JNU_PrintString(JNIEnv *env, char *hdr, jstring string); - -JNIEXPORT void JNICALL -JNU_PrintClass(JNIEnv *env, char *hdr, jobject object); - -JNIEXPORT jstring JNICALL -JNU_ToString(JNIEnv *env, jobject object); - -/* - * Package shorthand for use by native libraries - */ -#define JNU_JAVAPKG "java/lang/" -#define JNU_JAVAIOPKG "java/io/" -#define JNU_JAVANETPKG "java/net/" - -/* - * Check if the current thread is attached to the VM, and returns - * the JNIEnv of the specified version if the thread is attached. - * - * If the current thread is not attached, this function returns 0. - * - * If the current thread is attached, this function returns the - * JNI environment, or returns (void *)JNI_ERR if the specified - * version is not supported. - */ -JNIEXPORT void * JNICALL -JNU_GetEnv(JavaVM *vm, jint version); - -/* - * Warning free access to pointers stored in Java long fields. - */ -#define JNU_GetLongFieldAsPtr(env,obj,id) \ - (jlong_to_ptr((*(env))->GetLongField((env),(obj),(id)))) -#define JNU_SetLongFieldFromPtr(env,obj,id,val) \ - (*(env))->SetLongField((env),(obj),(id),ptr_to_jlong(val)) - -/* - * Internal use only. - */ -enum { - NO_ENCODING_YET = 0, /* "sun.jnu.encoding" not yet set */ - NO_FAST_ENCODING, /* Platform encoding is not fast */ - FAST_8859_1, /* ISO-8859-1 */ - FAST_CP1252, /* MS-DOS Cp1252 */ - FAST_646_US /* US-ASCII : ISO646-US */ -}; - -jstring nativeNewStringPlatform(JNIEnv *env, const char *str); - -char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy); - -int getFastEncoding(); - -void initializeEncoding(); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* JNI_UTIL_H */ diff --git a/native/IdeaWin32/readme.txt b/native/IdeaWin32/readme.txt new file mode 100644 index 000000000000..d3a99b387d3c --- /dev/null +++ b/native/IdeaWin32/readme.txt @@ -0,0 +1,9 @@ +Prerequisites: +- Visual Studio C++ 2010 Express +- Windows SDK 7.1 (native: Windows Headers, x86 Libraries, x64 Libraries, Tools, Visual C++ Compilers) +- JDK 1.6+ + +To build: +- open Property Manager, expand any configuration, open IdeaWin32 property page, and edit JAVA_HOME user macro + to point to a valid JDK installation +- build Release/Win32 and Release/x64 configurations diff --git a/native/IdeaWin32/stdafx.cpp b/native/IdeaWin32/stdafx.cpp deleted file mode 100644 index 9a99d3a2049d..000000000000 --- a/native/IdeaWin32/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// IdeaWin32.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/native/IdeaWin32/stdafx.h b/native/IdeaWin32/stdafx.h deleted file mode 100644 index 5cb1cb9f9e68..000000000000 --- a/native/IdeaWin32/stdafx.h +++ /dev/null @@ -1,30 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -// Modify the following defines if you have to target a platform prior to the ones specified below. -// Refer to MSDN for the latest info on corresponding values for different platforms. -#ifndef WINVER // Allow use of features specific to Windows XP or later. -#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. -#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. -#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. -#endif - -#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. -#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. -#endif - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include - -#include diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java index 15bf90ccec1f..08da83c4b290 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java @@ -20,7 +20,7 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.util.*; import com.intellij.psi.codeStyle.arrangement.ArrangementRule; -import com.intellij.psi.codeStyle.arrangement.ArrangementRuleUtil; +import com.intellij.psi.codeStyle.arrangement.ArrangementUtil; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; import org.intellij.lang.annotations.MagicConstant; @@ -120,6 +120,16 @@ public class CommonCodeStyleSettings { return myIndentOptions; } + @NotNull + public List getArrangementRules() { + return myArrangementRules; + } + + public void setArrangementRules(@NotNull List rules) { + myArrangementRules.clear(); + myArrangementRules.addAll(rules); + } + public CommonCodeStyleSettings clone(CodeStyleSettings rootSettings) { assert rootSettings != null; CommonCodeStyleSettings commonSettings = new CommonCodeStyleSettings(myLanguage, getFileType()); @@ -168,10 +178,7 @@ public class CommonCodeStyleSettings { private static void copyFieldValue(final Object from, Object to, final Field field) throws IllegalAccessException { Class fieldType = field.getType(); - if (fieldType.isPrimitive()) { - field.set(to, field.get(from)); - } - else if (fieldType.equals(String.class)) { + if (fieldType.isPrimitive() || fieldType.equals(String.class)) { field.set(to, field.get(from)); } else { @@ -202,7 +209,7 @@ public class CommonCodeStyleSettings { } Element arrangementRulesContainer = element.getChild(ARRANGEMENT_ELEMENT_NAME); if (arrangementRulesContainer != null) { - myArrangementRules.addAll(ArrangementRuleUtil.readExternal(arrangementRulesContainer, myLanguage)); + myArrangementRules.addAll(ArrangementUtil.readExternal(arrangementRulesContainer, myLanguage)); } } @@ -224,7 +231,7 @@ public class CommonCodeStyleSettings { if (!myArrangementRules.isEmpty()) { Element container = new Element(ARRANGEMENT_ELEMENT_NAME); - ArrangementRuleUtil.writeExternal(container, myArrangementRules, myLanguage); + ArrangementUtil.writeExternal(container, myArrangementRules, myLanguage); if (!container.getChildren().isEmpty()) { element.addContent(container); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntry.java index f29ed7d103a2..d3ad9f9eefee 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntry.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntry.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.codeStyle.arrangement; +import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -66,4 +67,15 @@ public interface ArrangementEntry { * to move rearranged entries */ int getEndOffset(); + + /** + * Sometimes we want particular entry to serve just as another entries holder. For example, we might want to arrange + * anonymous class entries but don't want the class itself, say, to be arranged with normal inner classes. + *

+ * That is achieved for entries which return 'false' from this method call. + * + * @return true if current entry can be {@link ArrangementEntryMatcher#isMatched(ArrangementEntry) matched}; + * false otherwise + */ + boolean canBeMatched(); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleUtil.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java similarity index 64% rename from platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleUtil.java rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java index 9d9c21da3533..520407ba89ba 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleUtil.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java @@ -16,6 +16,8 @@ package com.intellij.psi.codeStyle.arrangement; import com.intellij.lang.Language; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher; import com.intellij.psi.codeStyle.arrangement.match.CompositeArrangementEntryMatcher; import org.jdom.Element; @@ -30,9 +32,9 @@ import java.util.List; * @author Denis Zhdanov * @since 7/17/12 11:24 AM */ -public class ArrangementRuleUtil { +public class ArrangementUtil { - private ArrangementRuleUtil() { + private ArrangementUtil() { } //region Serialization @@ -141,4 +143,79 @@ public class ArrangementRuleUtil { return composite; } //endregion + + //region ArrangementEntry + + /** + * Tries to build a text range on the given arguments basis. It should conform to the criteria below: + *

+   * 
    + *
  • it's start offset is located at the start of the same line where given range starts;
  • + *
  • it's end offset is located at the end of the same line where given range ends;
  • + *
  • all symbols between the resulting range start offset and given range's start offset are white spaces or tabulations;
  • + *
  • all symbols between the given range's end offset and resulting range's end offset are white spaces or tabulations;
  • + *
+ *
+ * This method is expected to be used in a situation when we want to arrange complete rows. + * Example: + *
+   *   class Test {
+   *        void test() {
+   *        }
+   *      int i;
+   *   }
+   * 
+ * Suppose, we want to locate fields before methods. We can move the exact field and method range then but indent will be broken, + * i.e. we'll get the result below: + *
+   *   class Test {
+   *        int i;
+   *      void test() {
+   *        }
+   *   }
+   * 
+ * We can expand field and method range to the whole lines and that would allow to achieve the desired result: + *
+   *   class Test {
+   *      int i;
+   *        void test() {
+   *        }
+   *   }
+   * 
+ * + * @param initialRange anchor range + * @param text target text against which the ranges are built + * @return expanded range if possible; null otherwise + */ + @Nullable + public static TextRange expandToLine(@NotNull TextRange initialRange, @NotNull CharSequence text) { + int startOffsetToUse = initialRange.getStartOffset(); + for (int i = startOffsetToUse - 1; i >= 0; i--) { + char c = text.charAt(i); + if (!StringUtil.isWhiteSpace(c)) { + return null; + } + else if (c == '\n') { + break; + } + else { + startOffsetToUse = i; + } + } + + int endOffsetToUse = initialRange.getEndOffset(); + for (int i = endOffsetToUse; i < text.length(); i++) { + char c = text.charAt(i); + if (!StringUtil.isWhiteSpace(c)) { + return null; + } + else if (c == '\n') { + endOffsetToUse = i; + break; + } + } + + return TextRange.create(startOffsetToUse, endOffsetToUse); + } + //endregion } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementEntry.java new file mode 100644 index 000000000000..b580ee928f37 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementEntry.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2012 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.psi.codeStyle.arrangement; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author Denis Zhdanov + * @since 7/20/12 4:53 PM + */ +public class DefaultArrangementEntry implements ArrangementEntry { + + private final List myChildren = new ArrayList(); + + @Nullable ArrangementEntry myParent; + private final int myStartOffset; + private final int myEndOffset; + private final boolean myCanBeMatched; + + public DefaultArrangementEntry(@Nullable ArrangementEntry parent, int startOffset, int endOffset, boolean canBeMatched) { + myCanBeMatched = canBeMatched; + assert startOffset < endOffset; + myParent = parent; + myStartOffset = startOffset; + myEndOffset = endOffset; + } + + @Nullable + @Override + public ArrangementEntry getParent() { + return myParent; + } + + @NotNull + @Override + public Collection getChildren() { + return myChildren; + } + + public void addChild(@NotNull ArrangementEntry entry) { + myChildren.add(entry); + } + + @Override + public int getStartOffset() { + return myStartOffset; + } + + @Override + public int getEndOffset() { + return myEndOffset; + } + + @Override + public boolean canBeMatched() { + return myCanBeMatched; + } +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java index b8eb681b3704..617491fcf2bf 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java @@ -16,6 +16,7 @@ package com.intellij.psi.codeStyle.arrangement; import com.intellij.lang.LanguageExtension; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -33,15 +34,16 @@ import java.util.Collection; */ public interface Rearranger { - LanguageExtension> EXTENSION = new LanguageExtension>("com.intellij.rearranger.facade"); + LanguageExtension> EXTENSION = new LanguageExtension>("com.intellij.lang.rearranger"); /** * Allows to build rearranger-interested data for the given element. * - * @param root root element which children should be parsed for the rearrangement - * @param range target offsets range to use for filtering given root's children - * @return given root's children that are subject for further rearrangement + * @param root root element which children should be parsed for the rearrangement + * @param document document which corresponds to the target PSI tree + * @param ranges target offsets ranges to use for filtering given root's children + * @return given root's children which are subject for further rearrangement */ @NotNull - Collection parse(@NotNull PsiElement root, @NotNull TextRange range); + Collection parse(@NotNull PsiElement root, @NotNull Document document, @NotNull Collection ranges); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByNameArrangementEntryMatcher.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByNameArrangementEntryMatcher.java index 251c3c91f8dc..458c8763bb21 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByNameArrangementEntryMatcher.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByNameArrangementEntryMatcher.java @@ -35,9 +35,7 @@ public class ByNameArrangementEntryMatcher implements ArrangementEntryMatcher { public boolean isMatched(@NotNull ArrangementEntry entry) { if (entry instanceof NameAwareArrangementEntry) { String name = ((NameAwareArrangementEntry)entry).getName(); - if (name != null) { - return name.matches(myPattern); - } + return name != null && name.matches(myPattern); } return false; } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ModifierAwareArrangementEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ModifierAwareArrangementEntry.java index 10acb1bbd263..af25c6f904ac 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ModifierAwareArrangementEntry.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ModifierAwareArrangementEntry.java @@ -18,6 +18,8 @@ package com.intellij.psi.codeStyle.arrangement.match; import com.intellij.psi.codeStyle.arrangement.ArrangementEntry; import org.jetbrains.annotations.NotNull; +import java.util.Set; + /** * @author Denis Zhdanov * @since 7/17/12 8:57 PM @@ -25,5 +27,5 @@ import org.jetbrains.annotations.NotNull; public interface ModifierAwareArrangementEntry extends ArrangementEntry { @NotNull - ArrangementModifier getModifier(); + Set getModifiers(); } diff --git a/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementRuleSerializerTest.java b/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementRuleSerializerTest.java index 37948f38fa31..547b35b49b4f 100644 --- a/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementRuleSerializerTest.java +++ b/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementRuleSerializerTest.java @@ -17,7 +17,7 @@ package com.intellij.psi.codeStyle.arrangement.match; import com.intellij.psi.codeStyle.arrangement.ArrangementRule; import com.intellij.psi.codeStyle.arrangement.ArrangementRuleSerializer; -import com.intellij.psi.codeStyle.arrangement.ArrangementRuleUtil; +import com.intellij.psi.codeStyle.arrangement.ArrangementUtil; import com.intellij.psi.codeStyle.arrangement.DefaultArrangementRuleSerializer; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -48,13 +48,13 @@ public class DefaultArrangementRuleSerializerTest { @Test public void compositeMatchers() { - doTest(ArrangementRuleUtil.or( + doTest(ArrangementUtil.or( new ByTypeArrangementEntryMatcher(ArrangementEntryType.FIELD), new ByTypeArrangementEntryMatcher(ArrangementEntryType.METHOD)) ); - doTest(ArrangementRuleUtil.and( - ArrangementRuleUtil.or( + doTest(ArrangementUtil.and( + ArrangementUtil.or( new ByTypeArrangementEntryMatcher(ArrangementEntryType.METHOD), new ByNameArrangementEntryMatcher("get*") ) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/DocPreviewUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/DocPreviewUtil.java index 77994a63d9ae..63d95d730fca 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/DocPreviewUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/DocPreviewUtil.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.documentation.DocumentationManager; import com.intellij.lang.documentation.DocumentationProvider; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; +import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -36,6 +37,23 @@ import java.util.regex.Pattern; */ public class DocPreviewUtil { + private static final TIntHashSet ALLOWED_LINK_SEPARATORS = new TIntHashSet(); + static { + ALLOWED_LINK_SEPARATORS.add(','); + ALLOWED_LINK_SEPARATORS.add(' '); + ALLOWED_LINK_SEPARATORS.add('.'); + ALLOWED_LINK_SEPARATORS.add(';'); + ALLOWED_LINK_SEPARATORS.add('&'); + ALLOWED_LINK_SEPARATORS.add('\t'); + ALLOWED_LINK_SEPARATORS.add('\n'); + ALLOWED_LINK_SEPARATORS.add('['); + ALLOWED_LINK_SEPARATORS.add(']'); + ALLOWED_LINK_SEPARATORS.add('('); + ALLOWED_LINK_SEPARATORS.add(')'); + ALLOWED_LINK_SEPARATORS.add('<'); + ALLOWED_LINK_SEPARATORS.add('>'); + } + /** * We shorten links text from fully qualified name to short names (e.g. from 'java.lang.String' to 'String'). * There is a possible situation then that we have two replacements where one key is a simple name and another one is a fully qualified @@ -90,13 +108,16 @@ public class DocPreviewUtil { Map links = new HashMap(); process(fullText, new LinksCollector(links)); - // Add short names. + // Add derived names. Map toAdd = new HashMap(); for (Map.Entry entry : links.entrySet()) { - String key = entry.getKey(); - int i = key.lastIndexOf('.'); - if (i > 0 && i < key.length() - 1) { - toAdd.put(key.substring(i + 1), entry.getValue()); + String shortName = parseShortName(entry.getKey()); + if (shortName != null) { + toAdd.put(shortName, entry.getValue()); + } + String longName = parseLongName(entry.getKey(), entry.getValue()); + if (longName != null) { + toAdd.put(longName, entry.getValue()); } } links.putAll(toAdd); @@ -121,6 +142,40 @@ public class DocPreviewUtil { return buffer.toString(); } + /** + * Tries to build a short name form the given name assuming that it is a full name. + *

+ * Example: return {@code 'String'} for a given {@code 'java.lang.String'}. + * + * @param name name to process + * @return short name derived from the given full name if possible; null otherwise + */ + @Nullable + private static String parseShortName(@NotNull String name) { + int i = name.lastIndexOf('.'); + return i > 0 && i < name.length() - 1 ? name.substring(i + 1) : null; + } + + /** + * Tries to build a long name from the given short name and a link. + *

+ * Example: return {@code 'java.lang.String'} for a given pair (name {@code 'String'}; address: {@code 'psi_element://java.lang.String'}. + * + * @param shortName short name to process + * @param address address to process + * @return long name derived from the given arguments (if any); null otherwise + */ + @Nullable + private static String parseLongName(@NotNull String shortName, @NotNull String address) { + String pureAddress = address; + int i = pureAddress.lastIndexOf("//"); + if (i > 0 && i < pureAddress.length() - 2) { + pureAddress = pureAddress.substring(i + 2); + } + + return (pureAddress.equals(shortName) || !pureAddress.endsWith(shortName)) ? null : pureAddress; + } + private static void replace(@NotNull StringBuilder text, @NotNull String replaceFrom, @NotNull String replaceTo, @@ -131,6 +186,15 @@ public class DocPreviewUtil { if (intersects(readOnlyChanges, i, end)) { continue; } + if (end - i > 1 && end < text.length() && !ALLOWED_LINK_SEPARATORS.contains(text.charAt(end))) { + // Consider a situation when we have, say, replacement from text 'PsiType' and encounter a 'PsiTypeParameter' in the text. + // We don't want to perform the replacement then. + continue; + } + if (end - i > 1 && i > 0 && !ALLOWED_LINK_SEPARATORS.contains(text.charAt(i - 1))) { + // Similar situation but targets head match: from = 'TextRange', text = 'getTextRange()'. + continue; + } text.replace(i, end, replaceTo); int diff = replaceTo.length() - replaceFrom.length(); for (int j = 0; j < readOnlyChanges.size(); j++) { diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java new file mode 100644 index 000000000000..9072ca1c8b8a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java @@ -0,0 +1,232 @@ +/* + * Copyright 2000-2012 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.psi.codeStyle.arrangement.engine; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.arrangement.ArrangementEntry; +import com.intellij.psi.codeStyle.arrangement.ArrangementRule; +import com.intellij.psi.codeStyle.arrangement.Rearranger; +import com.intellij.util.containers.Stack; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * @author Denis Zhdanov + * @since 7/20/12 1:56 PM + */ +public class ArrangementEngine { + + /** + * Arranges given PSI root contents that belong to the given ranges. + * + * @param file target PSI root + * @param ranges target ranges to use within the given root + */ + @SuppressWarnings("MethodMayBeStatic") + public void arrange(@NotNull PsiFile file, @NotNull Collection ranges) { + final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); + if (document == null) { + return; + } + + CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(file.getProject()).getCurrentSettings(); + final List arrangementRules = settings.getCommonSettings(file.getLanguage()).getArrangementRules(); + if (arrangementRules.isEmpty()) { + return; + } + + Rearranger rearranger = Rearranger.EXTENSION.forLanguage(file.getLanguage()); + if (rearranger == null) { + return; + } + + final Collection entriesToProcess = rearranger.parse(file, document, ranges); + final DocumentEx documentEx; + if (document instanceof DocumentEx && !((DocumentEx)document).isInBulkUpdate()) { + documentEx = (DocumentEx)document; + } + else { + documentEx = null; + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + if (documentEx != null) { + documentEx.setInBulkUpdate(true); + } + try { + doArrange(document, arrangementRules, entriesToProcess); + } + finally { + if (documentEx != null) { + documentEx.setInBulkUpdate(false); + } + } + } + }); + } + + private static void doArrange(@NotNull final Document document, + @NotNull List arrangementRules, + @NotNull Collection entriesToProcess) + { + // The general idea is to process entries bottom-up where every processed group belongs to the same parent. We may not bother + // with entries text ranges then. We use a list and a stack for achieving that than. + // + // Example: + // Entry1 Entry2 + // / \ / \ + // Entry11 Entry12 Entry21 Entry22 + // + // -------------------------- + // Stage 1: + // list: Entry1 Entry2 + // stack: [0, 0, 2] + // -------------------------- + // Stage 2: + // list: Entry1 Entry2 Entry11 Entry12 + // stack: [0, 1, 2] + // [2, 2, 4] + // -------------------------- + // Stage 3: + // list: Entry1 Entry2 Entry11 Entry12 + // stack: [0, 1, 2] + // [2, 3, 4] + // -------------------------- + // Stage 4: + // list: Entry1 Entry2 Entry11 Entry12 + // stack: [0, 1, 2] + // [2, 4, 4] + // -------------------------- + // arrange 'Entry11 Entry12' + // -------------------------- + // Stage 5: + // list: Entry1 Entry2 + // stack: [0, 1, 2] + // -------------------------- + // Stage 6: + // list: Entry1 Entry2 Entry21 Entry22 + // stack: [0, 2, 2] + // [2, 2, 4] + // -------------------------- + // Stage 7: + // list: Entry1 Entry2 Entry21 Entry22 + // stack: [0, 2, 2] + // [2, 3, 4] + // -------------------------- + // Stage 8: + // list: Entry1 Entry2 Entry21 Entry22 + // stack: [0, 2, 2] + // [2, 4, 4] + // -------------------------- + // arrange 'Entry21 Entry22' + // -------------------------- + // Stage 9: + // list: Entry1 Entry2 + // stack: [0, 2, 2] + // -------------------------- + // arrange 'Entry1 Entry2' + + List entries = new ArrayList(); + Stack stack = new Stack(); + entries.addAll(entriesToProcess); + stack.push(new StackEntry(0, entriesToProcess.size())); + while (!stack.isEmpty()) { + StackEntry stackEntry = stack.peek(); + if (stackEntry.current >= stackEntry.end) { + List subEntries = entries.subList(stackEntry.start, stackEntry.end); + if (subEntries.size() > 1) { + doArrange(arrangementRules, subEntries, document); + } + subEntries.clear(); + stack.pop(); + } + else { + ArrangementEntry entry = entries.get(stackEntry.current++); + Collection children = entry.getChildren(); + if (!children.isEmpty()) { + entries.addAll(children); + stack.push(new StackEntry(stackEntry.end, children.size())); + } + } + } + } + + private static void doArrange(@NotNull List rules, + @NotNull List entries, + @NotNull Document document) + { + List arranged = new ArrayList(); + Set unprocessed = new LinkedHashSet(entries); + + for (ArrangementRule rule : rules) { + for (ArrangementEntry entry : entries) { + if (entry.canBeMatched() && unprocessed.contains(entry) && rule.getMatcher().isMatched(entry)) { + arranged.add(entry); + unprocessed.remove(entry); + } + } + } + arranged.addAll(unprocessed); + + if (arranged.equals(entries)) { + return; + } + + // We apply changes from the last position to the first position in order not to bother with offsets shifts. + ArrangementEntry parent = entries.get(0).getParent(); + final String initial; + final int shift; + if (parent == null) { + initial = document.getCharsSequence().toString(); + shift = 0; + } + else { + initial = document.getCharsSequence().subSequence(parent.getStartOffset(), parent.getEndOffset()).toString(); + shift = parent.getStartOffset(); + } + for (int i = arranged.size() - 1; i >= 0; i--) { + ArrangementEntry arrangedEntry = arranged.get(i); + ArrangementEntry initialEntry = entries.get(i); + if (!arrangedEntry.equals(initialEntry)) { + String text = initial.substring(arrangedEntry.getStartOffset() - shift, arrangedEntry.getEndOffset() - shift); + document.replaceString(initialEntry.getStartOffset(), initialEntry.getEndOffset(), text); + } + } + } + + private static class StackEntry { + + public int start; + public int current; + public int end; + + StackEntry(int start, int count) { + this.start = start; + current = start; + end = start + count; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java index f1c897706ff5..233d8a417664 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java @@ -104,7 +104,7 @@ public abstract class InplaceRefactoring { protected String myAdvertisementText; private ArrayList myHighlighters; protected String myInitialName; - protected final String myOldName; + protected String myOldName; protected RangeMarker myBeforeRevert = null; protected String myInsertedName; protected LinkedHashSet myNameSuggestions; @@ -273,6 +273,14 @@ public abstract class InplaceRefactoring { return true; } else { + + if (!ourRenamersStack.isEmpty() && ourRenamersStack.peek() == this) { + ourRenamersStack.pop(); + if (!ourRenamersStack.empty()) { + myOldName = ourRenamersStack.peek().myOldName; + } + } + revertState(); final TemplateState templateState = TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(myEditor)); if (templateState != null) { diff --git a/platform/lang-impl/testSources/com/intellij/codeInsight/navigation/DocPreviewUtilTest.groovy b/platform/lang-impl/testSources/com/intellij/codeInsight/navigation/DocPreviewUtilTest.groovy index a7799d0b61a0..22df21db934c 100644 --- a/platform/lang-impl/testSources/com/intellij/codeInsight/navigation/DocPreviewUtilTest.groovy +++ b/platform/lang-impl/testSources/com/intellij/codeInsight/navigation/DocPreviewUtilTest.groovy @@ -145,4 +145,41 @@ Qname''' assertEquals(expected, DocPreviewUtil.buildPreview(header, null, fullText)) } + + @Test + void tailSubstrings() { + def header = '''\ +PsiResolveHelperImpl +public static com.intellij.openapi.util.Pair<com.intellij.psi.PsiType, com.intellij.psi.ConstraintType> getSubstitutionForTypeParameterConstraint (com.intellij.psi.PsiTypeParameter typeParam, com.intellij.psi.PsiType param, com.intellij.psi.PsiType arg, boolean isContraVariantPosition, com.intellij.pom.java.LanguageLevel languageLevel)''' + + def fullText = '''\ + com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl

@Nullable public static Pair<PsiType, ConstraintType> getSubstitutionForTypeParameterConstraint(PsiTypeParameter typeParam,
+                                                                                  PsiType param,
+                                                                                  PsiType arg,
+                                                                                  boolean isContraVariantPosition,
+                                                                                  LanguageLevel languageLevel)
''' + + def expected = '''\ +PsiResolveHelperImpl
public static Pair<PsiType, ConstraintType> getSubstitutionForTypeParameterConstraint (PsiTypeParameter typeParam, PsiType param, PsiType arg, boolean isContraVariantPosition, LanguageLevel languageLevel)''' + + assertEquals(expected, DocPreviewUtil.buildPreview(header, null, fullText)) + } + + @Test + void headSubstrings() { + def header = '''\ +ASTNode +com.intellij.openapi.util.TextRange getTextRange ()''' + + def fullText = '''\ + com.intellij.lang.ASTNode
TextRange getTextRange()
+ Returns the text range (a combination of starting offset in the document and length) for this node. + +
Returns:
the text range.
''' + + def expected = '''\ +ASTNode
TextRange getTextRange ()''' + + assertEquals(expected, DocPreviewUtil.buildPreview(header, null, fullText)) + } } diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java index b67783afd0a3..5c29f06bb730 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java @@ -96,7 +96,7 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith public void setUI(final TreeUI ui) { TreeUI actualUI = ui; if (!isCustomUI()) { - if (!(ui instanceof WideSelectionTreeUI) /*&& UIUtil.isUnderAquaBasedLookAndFeel()*/) { + if (!(ui instanceof WideSelectionTreeUI) && (UIUtil.isUnderAquaBasedLookAndFeel() || SystemInfo.isWindows)) { //todo[kb] fix on ubunty actualUI = new WideSelectionTreeUI(isMacWideSelection(), !isFileColorsEnabled()); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java index 7d29e02c02a6..a1c851382371 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java @@ -38,6 +38,7 @@ import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.awt.RelativePoint; @@ -52,6 +53,8 @@ import java.awt.event.MouseEvent; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class ShowFilePathAction extends AnAction { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ShowFilePathAction"); @@ -61,7 +64,9 @@ public class ShowFilePathAction extends AnAction { @Override protected Boolean compute() { final String version = ExecUtil.execAndReadLine("nautilus", "--version"); - return version != null && version.startsWith("GNOME nautilus 3"); + if (version == null) return false; + final Matcher m = Pattern.compile("GNOME nautilus ([0-9.]+)").matcher(version); + return m.find() && StringUtil.compareVersionNumbers(m.group(1), "3") >= 0; } }; diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index 7ae2704d4156..5990ab296dce 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -19,16 +19,12 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.plugins.*; import com.intellij.ide.reporter.ConnectionException; import com.intellij.ide.util.PropertiesComponent; -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationType; -import com.intellij.notification.Notifications; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationInfo; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; +import com.intellij.notification.*; +import com.intellij.openapi.application.*; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginId; +import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -40,6 +36,8 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.IdeFrame; +import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.util.PlatformUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.io.UrlConnectionUtil; @@ -54,6 +52,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.HyperlinkEvent; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; @@ -451,10 +450,24 @@ public final class UpdateChecker { dialog.setModal(alwaysShowResults); dialog.show(); } - else if (updatedPlugins != null || alwaysShowResults) { + else if (updatedPlugins != null) { NoUpdatesDialog dialog = new NoUpdatesDialog(true, updatedPlugins, enableLink); dialog.setShowConfirmation(showConfirmation); dialog.show(); + } else if (alwaysShowResults) { + final String title = IdeBundle.message("updates.info.dialog.title"); + final String message = "You already have the latest version of " + ApplicationInfo.getInstance().getVersionName() + " installed.
" + + "To configure automatic update settings, see the Updates dialog of your IDE settings"; + NotificationGroup.balloonGroup("update.available.group") + .createNotification(title, message, NotificationType.INFORMATION, new NotificationListener() { + @Override + public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { + notification.expire(); + final UpdateSettingsConfigurable configurable = new UpdateSettingsConfigurable(); + IdeFrame ideFrame = WindowManagerEx.getInstanceEx().findFrameFor(null); + ShowSettingsUtil.getInstance().editConfigurable((JFrame)ideFrame, configurable); + } + }).notify(null); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java index 1ab273622a04..743dbcb93d69 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java @@ -20,7 +20,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileAttributes; import com.intellij.openapi.util.io.FileUtil; @@ -43,23 +42,18 @@ import java.io.OutputStream; import java.util.*; public class JarFileSystemImpl extends JarFileSystem implements ApplicationComponent { + @NonNls private static final String IDEA_JARS_NOCOPY = "idea.jars.nocopy"; + + private static final class JarFileSystemImplLock { } + private static final Object LOCK = new JarFileSystemImplLock(); + private final Set myNoCopyJarPaths = SystemInfo.isFileSystemCaseSensitive ? new ConcurrentHashSet() : new ConcurrentHashSet(CaseInsensitiveStringHashingStrategy.INSTANCE); - - private final static Logger LOG = Logger.getInstance(JarFileSystemImpl.class); - - @NonNls private static final String IDEA_JARS_NOCOPY = "idea.jars.nocopy"; - private File myNoCopyJarDir; - private final Map myHandlers = new HashMap(); + private File myNoCopyJarDir; private String[] jarPathsCache; // jarPathsCache = myHandlers.keySet() - private static final class JarFileSystemImplLock { - } - - private static final Object LOCK = new JarFileSystemImplLock(); - public JarFileSystemImpl(MessageBus bus) { bus.connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { @Override @@ -107,7 +101,7 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo } } - VirtualFile[] roots = VfsUtil.toVirtualFileArray(rootsToRefresh); + VirtualFile[] roots = VfsUtilCore.toVirtualFileArray(rootsToRefresh); RefreshQueue.getInstance().refresh(false, true, null, roots); } }; @@ -301,8 +295,8 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo } @Override - public void setTimeStamp(@NotNull final VirtualFile file, final long modstamp) throws IOException { - getHandler(file).setTimeStamp(file, modstamp); + public void setTimeStamp(@NotNull final VirtualFile file, final long modStamp) throws IOException { + getHandler(file).setTimeStamp(file, modStamp); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/IdeaWin32.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/IdeaWin32.java deleted file mode 100644 index 3e5e0cf6048a..000000000000 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/IdeaWin32.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2000-2011 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.vfs.impl.win32; - -/** - * @author Dmitry Avdeev - */ -public class IdeaWin32 { - public native FileInfo getInfo(String path); - - public native FileInfo[] listChildren(String path); -} diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java index 6440e70f5565..09c21e205a1c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java @@ -16,6 +16,8 @@ package com.intellij.openapi.vfs.impl.win32; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.win32.FileInfo; +import com.intellij.openapi.util.io.win32.IdeaWin32; import com.intellij.util.ArrayUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -29,14 +31,13 @@ import java.util.Map; * @author Dmitry Avdeev */ public class Win32Kernel { - public static final int FILE_ATTRIBUTE_READONLY = 0x0001; - public static final int FILE_ATTRIBUTE_HIDDEN = 0x0002; - public static final int FILE_ATTRIBUTE_DIRECTORY = 0x0010; - public static final int FILE_ATTRIBUTE_DEVICE = 0x0040; - public static final int FILE_ATTRIBUTE_REPARSE_POINT = 0x0400; - - private final IdeaWin32 myKernel = new IdeaWin32(); + public static final int FILE_ATTRIBUTE_READONLY = FileInfo.FILE_ATTRIBUTE_READONLY; + public static final int FILE_ATTRIBUTE_HIDDEN = FileInfo.FILE_ATTRIBUTE_HIDDEN; + public static final int FILE_ATTRIBUTE_DIRECTORY = FileInfo.FILE_ATTRIBUTE_DIRECTORY; + public static final int FILE_ATTRIBUTE_DEVICE = FileInfo.FILE_ATTRIBUTE_DEVICE; + public static final int FILE_ATTRIBUTE_REPARSE_POINT = FileInfo.FILE_ATTRIBUTE_REPARSE_POINT; + private final IdeaWin32 myKernel = IdeaWin32.getInstance(); private final Map myCache = new THashMap(); void clearCache() { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java index 0cec37f27b18..113926d3e8bd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java @@ -15,11 +15,11 @@ */ package com.intellij.openapi.vfs.impl.win32; -import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileAttributes; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.win32.FileInfo; +import com.intellij.openapi.util.io.win32.IdeaWin32; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.local.LocalFileSystemBase; import com.intellij.util.ArrayUtil; @@ -39,40 +39,8 @@ import static com.intellij.util.BitUtil.isSet; public class Win32LocalFileSystem extends LocalFileSystemBase { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem"); - private static final boolean ourIsAvailable; - - static { - boolean available = false; - if (SystemInfo.isWindows) { - String libName = SystemInfo.is64Bit ? "IdeaWin64" : "IdeaWin32"; - try { - System.load(PathManager.getHomePath() + "/community/bin/win/" + libName + ".dll"); - available = true; - } - catch (Throwable t0) { - try { - System.load(PathManager.getHomePath() + "/bin/win/" + libName + ".dll"); - available = true; - } - catch (Throwable t1) { - try { - System.loadLibrary(libName); - available = true; - } - catch (Throwable t2) { - LOG.warn("Failed to load native filesystem for Windows", t2); - } - } - } - } - ourIsAvailable = available; - if (available) { - LOG.info("Native filesystem for Windows is operational"); - } - } - public static boolean isAvailable() { - return ourIsAvailable; + return IdeaWin32.isAvailable(); } private static final ThreadLocal THREAD_LOCAL = new ThreadLocal() { diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 187bb8a1311b..5f657f13666a 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -123,6 +123,7 @@ beanClass="com.intellij.lang.LanguageExtensionPoint"/> + diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 1f635d2026e8..302bc00f4117 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -177,6 +177,8 @@ + + diff --git a/platform/util/src/com/intellij/openapi/util/SystemInfo.java b/platform/util/src/com/intellij/openapi/util/SystemInfo.java index b2e0e9fb2c2e..2f86c51de7d8 100644 --- a/platform/util/src/com/intellij/openapi/util/SystemInfo.java +++ b/platform/util/src/com/intellij/openapi/util/SystemInfo.java @@ -56,7 +56,7 @@ public class SystemInfo extends SystemInfoRt { public static final boolean isFileSystemCaseSensitive = SystemInfoRt.isFileSystemCaseSensitive; public static final boolean areSymLinksSupported = isUnix || - isWindows && OS_VERSION.compareTo("6.0") >= 0 && isJavaVersionAtLeast("1.7"); + isWindows && OS_VERSION.compareTo("6.0") >= 0; public static final boolean is32Bit = ARCH_DATA_MODEL == null || ARCH_DATA_MODEL.equals("32"); public static final boolean is64Bit = !is32Bit; diff --git a/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java index e38a99e630a1..abf9063d28ad 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java @@ -17,6 +17,8 @@ package com.intellij.openapi.util.io; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.win32.FileInfo; +import com.intellij.openapi.util.io.win32.IdeaWin32; import com.intellij.util.ArrayUtil; import com.intellij.util.SystemProperties; import com.sun.jna.Library; @@ -65,7 +67,17 @@ public class FileSystemUtil { final String quickTestPath = SystemInfo.isWindows ? "C:\\" : "/"; if (!forceUseNio2) { - if (SystemInfo.isLinux || SystemInfo.isMac || SystemInfo.isSolaris || SystemInfo.isFreeBSD) { + if (SystemInfo.isWindows) { + try { + final Mediator mediator = new IdeaWin32MediatorImpl(); + mediator.getAttributes(quickTestPath); + return mediator; + } + catch (Throwable t) { + LOG.warn(t); + } + } + else if (SystemInfo.isLinux || SystemInfo.isMac || SystemInfo.isSolaris || SystemInfo.isFreeBSD) { try { final Mediator mediator = new JnaUnixMediatorImpl(); mediator.getAttributes(quickTestPath); @@ -330,6 +342,44 @@ public class FileSystemUtil { } + private static class IdeaWin32MediatorImpl implements Mediator { + private static final String PATH_PREFIX = "\\\\?\\"; + private static final int PREFIX_SIZE = PATH_PREFIX.length(); + + private IdeaWin32 myInstance = IdeaWin32.getInstance(); + + @Override + public FileAttributes getAttributes(@NotNull final String path) throws Exception { + final FileInfo fileInfo = myInstance.getInfo(path); + if (fileInfo == null) return null; + + final boolean isDirectory = isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_DIRECTORY); + final boolean isSpecial = isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_DEVICE); + final boolean isSymlink = isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_REPARSE_POINT); + final boolean isHidden = isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_HIDDEN); + final boolean isWritable = !isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_READONLY); + final long timestamp = fileInfo.timestamp / 10000 - 11644473600000l; + return new FileAttributes(isDirectory, isSpecial, isSymlink, isHidden, fileInfo.length, timestamp, isWritable); + } + + @Override + public String resolveSymLink(@NotNull final String path) throws Exception { + final String result = myInstance.resolveSymLink(path); + return result != null && result.startsWith(PATH_PREFIX) ? result.substring(PREFIX_SIZE) : result; + } + + @Override + public void setPermissions(@NotNull final String path, final int permissions) throws Exception { + } + + @NotNull + @Override + public String getName() { + return "IdeaWin32"; + } + } + + // thanks to SVNKit for the idea private static class JnaUnixMediatorImpl implements Mediator { @SuppressWarnings("OctalInteger") diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/FileInfo.java b/platform/util/src/com/intellij/openapi/util/io/win32/FileInfo.java similarity index 61% rename from platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/FileInfo.java rename to platform/util/src/com/intellij/openapi/util/io/win32/FileInfo.java index 52cdc416ac7f..88693715ac78 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/FileInfo.java +++ b/platform/util/src/com/intellij/openapi/util/io/win32/FileInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -13,26 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.vfs.impl.win32; +package com.intellij.openapi.util.io.win32; import org.intellij.lang.annotations.MagicConstant; /** + * Do not use this class directly. + * * @author Dmitry Avdeev + * @since 12.0 */ public class FileInfo { - - static { - initIDs(); - } - - private static native void initIDs(); + public static final int FILE_ATTRIBUTE_READONLY = 0x0001; + public static final int FILE_ATTRIBUTE_HIDDEN = 0x0002; + public static final int FILE_ATTRIBUTE_DIRECTORY = 0x0010; + public static final int FILE_ATTRIBUTE_DEVICE = 0x0040; + public static final int FILE_ATTRIBUTE_REPARSE_POINT = 0x0400; // is set only for symlinks public String name; - - @MagicConstant(flagsFromClass = Win32Kernel.class) + @MagicConstant(flagsFromClass = FileInfo.class) public int attributes; - public long timestamp; public long length; diff --git a/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java b/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java new file mode 100644 index 000000000000..2e81a993d365 --- /dev/null +++ b/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2012 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.util.io.win32; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; +import org.jetbrains.annotations.NotNull; + +/** + * Do not use this class directly. + * + * @author Dmitry Avdeev + * @since 12.0 + */ +public class IdeaWin32 { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.io.win32.Win32LocalFileSystem"); + + private static final IdeaWin32 ourInstance; + + static { + boolean available = false; + if (SystemInfo.isWindows) { + String libName = SystemInfo.is64Bit ? "IdeaWin64" : "IdeaWin32"; + try { + System.load(PathManager.getHomePath() + "/community/bin/win/" + libName + ".dll"); + available = true; + } + catch (Throwable t0) { + try { + System.load(PathManager.getHomePath() + "/bin/win/" + libName + ".dll"); + available = true; + } + catch (Throwable t1) { + try { + System.loadLibrary(libName); + available = true; + } + catch (Throwable t2) { + LOG.warn("Failed to load native filesystem for Windows", t2); + } + } + } + } + + IdeaWin32 instance = null; + if (available) { + try { + instance = new IdeaWin32(); + LOG.info("Native filesystem for Windows is operational"); + } + catch (Throwable t) { + LOG.warn("Failed to initialize native filesystem for Windows", t); + } + } + ourInstance = instance; + } + + public static boolean isAvailable() { + return ourInstance != null; + } + + @NotNull + public static IdeaWin32 getInstance() { + if (!isAvailable()) { + throw new IllegalStateException("Native filesystem for Windows is not loaded"); + } + return ourInstance; + } + + private IdeaWin32() { + initIDs(); + } + + private static native void initIDs(); + + public native FileInfo getInfo(String path); + + public native String resolveSymLink(String path); + + public native FileInfo[] listChildren(String path); +} diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 62e9ef562fea..ec9efc4e0729 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -1163,6 +1163,17 @@ public class StringUtil extends StringUtilRt { return join((Iterable)items, f, separator); } + public static String join(@NotNull Iterable items, @NotNull @NonNls String separator) { + StringBuilder result = new StringBuilder(); + for (Object item : items) { + result.append(item).append(separator); + } + if (result.length() > 0) { + result.setLength(result.length() - 1); + } + return result.toString(); + } + @NotNull public static String join(@NotNull Iterable items, @NotNull Function f, @NotNull @NonNls String separator) { final StringBuilder result = new StringBuilder(); diff --git a/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java b/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java index 917a503c6a5a..6ab5d652a07e 100644 --- a/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java +++ b/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java @@ -283,15 +283,17 @@ public class WideSelectionTreeUI extends BasicTreeUI { } } else { - //Color bg = tree.hasFocus() ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeUnfocusedSelectionBackground(); - //if (!selected) { - // bg = background; - //} + if (UIUtil.isUnderAquaBasedLookAndFeel()) { + Color bg = tree.hasFocus() ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeUnfocusedSelectionBackground(); + if (!selected) { + bg = background; + } - //if (/*myAlwaysPaintRowBackground || */selected) { - // rowGraphics.setColor(bg); - // rowGraphics.fillRect(xOffset, bounds.y, containerWidth, bounds.height - 1); - //} + if (myAlwaysPaintRowBackground || selected) { + rowGraphics.setColor(bg); + rowGraphics.fillRect(xOffset, bounds.y, containerWidth, bounds.height - 1); + } + } } if (shouldPaintExpandControl(path, row, isExpanded, hasBeenExpanded, isLeaf)) { @@ -308,7 +310,7 @@ public class WideSelectionTreeUI extends BasicTreeUI { @Override public void paint(Graphics g, JComponent c) { - if (myAlwaysPaintRowBackground && myWideSelection) { + if (myAlwaysPaintRowBackground && myWideSelection && !UIUtil.isUnderAquaBasedLookAndFeel()) { paintSelectedRows(g, ((JTree)c)); } if (myWideSelection) { diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesNio2ReadingTest.java b/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesNio2ReadingTest.java index 68f2e88ae01e..d1d2c395ef53 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesNio2ReadingTest.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesNio2ReadingTest.java @@ -17,7 +17,6 @@ package com.intellij.openapi.util.io; import com.intellij.openapi.util.SystemInfo; import org.junit.AfterClass; -import org.junit.Before; import org.junit.BeforeClass; import static org.junit.Assert.assertEquals; @@ -26,6 +25,8 @@ import static org.junit.Assume.assumeTrue; public class FileAttributesNio2ReadingTest extends FileAttributesReadingTest { @BeforeClass public static void setUpClass() throws Exception { + assumeTrue(SystemInfo.isJavaVersionAtLeast("1.7")); + System.setProperty(FileSystemUtil.FORCE_USE_NIO2_KEY, "true"); FileSystemUtil.resetMediator(); assertEquals("NIO2", FileSystemUtil.getMediatorName()); @@ -36,11 +37,4 @@ public class FileAttributesNio2ReadingTest extends FileAttributesReadingTest { System.setProperty(FileSystemUtil.FORCE_USE_NIO2_KEY, ""); FileSystemUtil.resetMediator(); } - - @Override - @Before - public void setUp() throws Exception { - assumeTrue(SystemInfo.isJavaVersionAtLeast("1.7")); - super.setUp(); - } } diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java b/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java index da880c0560f3..c763ffa657db 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java @@ -47,7 +47,8 @@ public class IoTestUtil { assertEquals(commandLine.command().toString(), 0, res); final File targetFile = new File(target); - assertEquals("target=" + target + ", link=" + linkFile, targetFile.exists(), linkFile.exists()); + final boolean shouldExist = targetFile.exists() || SystemInfo.isWindows && SystemInfo.JAVA_VERSION.startsWith("1.6"); + assertEquals("target=" + target + ", link=" + linkFile, shouldExist, linkFile.exists()); return linkFile; } } diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties index 98fd6cb89e9f..a991cb90d471 100644 --- a/plugins/android/resources/messages/AndroidBundle.properties +++ b/plugins/android/resources/messages/AndroidBundle.properties @@ -417,4 +417,7 @@ cannot.find.zip.align=The zipalign tool was not found in the SDK.\n\nPlease upda file.name.not.specified.error=File name is not specified root.element.not.specified.error=Root element is not specified directory.not.specified.error=Directory is not specified -android.manifest.merger.not.supported.error=Manifest merging is not supported. Please, reconfigure your manifest files \ No newline at end of file +android.manifest.merger.not.supported.error=Manifest merging is not supported. Please, reconfigure your manifest files +invalid.file.resource.name.error=Resource file name must contain only lowercase a-z, 0-9, or _ +invalid.file.resource.name.error1=Invalid resource file name +invalid.resource.name.error=Invalid resource name ''{0}'' \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileDialog.java b/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileDialog.java index ecd4adbde004..a4bd770f4830 100644 --- a/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileDialog.java +++ b/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileDialog.java @@ -34,6 +34,7 @@ import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.uipreview.DeviceConfiguratorPanel; import org.jetbrains.android.uipreview.InvalidOptionValueException; import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.android.util.ModuleListCellRendererWrapper; import org.jetbrains.annotations.NotNull; @@ -252,6 +253,12 @@ public class CreateResourceFileDialog extends DialogWrapper { Messages.showErrorDialog(myPanel, AndroidBundle.message("directory.not.specified.error"), CommonBundle.getErrorTitle()); return; } + + final String errorMessage = AndroidResourceUtil.getInvalidResourceFileNameMessage(fileName); + if (errorMessage != null) { + Messages.showErrorDialog(myPanel, errorMessage, CommonBundle.getErrorTitle()); + return; + } myValidator = createValidator(subdirName); if (myValidator == null || myValidator.checkInput(fileName) && myValidator.canClose(fileName)) { super.doOKAction(); diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java b/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java index 10074fea9763..d067378f1d2b 100644 --- a/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java +++ b/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java @@ -27,6 +27,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidatorEx; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiDirectory; @@ -78,7 +79,7 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase { @NotNull @Override protected PsiElement[] invokeDialog(Project project, PsiDirectory directory) { - MyInputValidator validator = new MyInputValidator(project, directory); + MyInputValidator validator = new MyValidator(project, directory); Messages.showInputDialog(project, AndroidBundle.message("new.file.dialog.text"), AndroidBundle.message("new.typed.resource.dialog.title", myResourcePresentableName), Messages.getQuestionIcon(), "", validator); @@ -203,4 +204,20 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase { } throw new IllegalArgumentException("Incorrect resource folder type"); } + + private class MyValidator extends MyInputValidator implements InputValidatorEx { + public MyValidator(Project project, PsiDirectory directory) { + super(project, directory); + } + + @Override + public boolean checkInput(String inputString) { + return getErrorText(inputString) == null; + } + + @Override + public String getErrorText(String inputString) { + return AndroidResourceUtil.getInvalidResourceFileNameMessage(inputString); + } + } } diff --git a/plugins/android/src/org/jetbrains/android/dom/resources/ResourceElement.java b/plugins/android/src/org/jetbrains/android/dom/resources/ResourceElement.java index d870c9971240..7d18b9f8b035 100644 --- a/plugins/android/src/org/jetbrains/android/dom/resources/ResourceElement.java +++ b/plugins/android/src/org/jetbrains/android/dom/resources/ResourceElement.java @@ -15,6 +15,7 @@ */ package org.jetbrains.android.dom.resources; +import com.intellij.util.xml.Convert; import com.intellij.util.xml.GenericAttributeValue; import com.intellij.util.xml.GenericDomValue; import com.intellij.util.xml.Required; @@ -25,5 +26,6 @@ import org.jetbrains.android.dom.AndroidDomElement; */ public interface ResourceElement extends GenericDomValue, AndroidDomElement { @Required + @Convert(ResourceNameConverter.class) GenericAttributeValue getName(); } diff --git a/plugins/android/src/org/jetbrains/android/dom/resources/ResourceNameConverter.java b/plugins/android/src/org/jetbrains/android/dom/resources/ResourceNameConverter.java new file mode 100644 index 000000000000..27970394b212 --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/dom/resources/ResourceNameConverter.java @@ -0,0 +1,30 @@ +package org.jetbrains.android.dom.resources; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.xml.ConvertContext; +import com.intellij.util.xml.Converter; +import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidResourceUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; + +/** + * @author Eugene.Kudelevsky + */ +public class ResourceNameConverter extends Converter { + @Override + public String fromString(@Nullable @NonNls String s, ConvertContext context) { + return s != null && StringUtil.isJavaIdentifier(AndroidResourceUtil.getFieldNameByResourceName(s)) + ? s : null; + } + + @Override + public String toString(@Nullable String s, ConvertContext context) { + return s; + } + + @Override + public String getErrorMessage(@Nullable String s, ConvertContext context) { + return AndroidBundle.message("invalid.resource.name.error", s); + } +} diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidAppPropertiesEditor.form b/plugins/android/src/org/jetbrains/android/newProject/AndroidAppPropertiesEditor.form index f43a933de4c7..05279b1e407c 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidAppPropertiesEditor.form +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidAppPropertiesEditor.form @@ -51,7 +51,7 @@ - + diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidAppPropertiesEditor.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidAppPropertiesEditor.java index 698b7319a208..84bbbc2fb2d1 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidAppPropertiesEditor.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidAppPropertiesEditor.java @@ -18,11 +18,15 @@ package org.jetbrains.android.newProject; import com.intellij.lexer.JavaLexer; import com.intellij.lexer.Lexer; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.JavaTokenType; import com.intellij.ui.DocumentAdapter; import com.intellij.util.ui.UIUtil; +import org.jetbrains.android.dom.manifest.Manifest; +import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.util.AndroidBundle; import org.jetbrains.android.util.AndroidCommonUtils; import org.jetbrains.annotations.NotNull; @@ -45,11 +49,16 @@ public class AndroidAppPropertiesEditor { private JLabel myErrorLabel; private JPanel myContentPanel; - private final String myModuleName; + private final ModulesProvider myModulesProvider; + private boolean myApp; - public AndroidAppPropertiesEditor(String moduleName) { - myModuleName = moduleName; - myApplicationNameField.setText(moduleName); + public AndroidAppPropertiesEditor(String moduleName, ModulesProvider modulesProvider) { + myModulesProvider = modulesProvider; + + if (moduleName != null) { + myApplicationNameField.setText(moduleName); + myPackageNameField.setText(getDefaultPackageNameByModuleName(moduleName)); + } myHelloAndroidCheckBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { updateActivityPanel(); @@ -58,7 +67,7 @@ public class AndroidAppPropertiesEditor { myPackageNameField.getDocument().addDocumentListener(new DocumentAdapter() { @Override protected void textChanged(DocumentEvent e) { - String message = validatePackageName(); + String message = validatePackageName(!myApp); myErrorLabel.setText(message); } }); @@ -71,12 +80,51 @@ public class AndroidAppPropertiesEditor { }); } + public void update(boolean app) { + myApplicationNameField.setEnabled(app); + myHelloAndroidCheckBox.setEnabled(app); + if (app) { + updateActivityPanel(); + } + else { + UIUtil.setEnabled(myActivtiyPanel, app, true); + } + myApp = app; + final String message = validatePackageName(!app); + myErrorLabel.setText(message); + } + + @NotNull + public static String getDefaultPackageNameByModuleName(@NotNull String moduleName) { + return "com.example." + toIdentifier(moduleName); + } + + @NotNull + private static String toIdentifier(@NotNull String s) { + final StringBuilder result = new StringBuilder(); + + for (int i = 0, n = s.length(); i < n; i++) { + final char c = s.charAt(i); + + if (Character.isJavaIdentifierPart(c)) { + if (i == 0 && !Character.isJavaIdentifierStart(c)) { + result.append('_'); + } + result.append(c); + } + else { + result.append('_'); + } + } + return result.toString(); + } + public void updateActivityPanel() { myErrorLabel.setForeground(Color.RED); UIUtil.setEnabled(myActivtiyPanel, myHelloAndroidCheckBox.isSelected(), true); } - private String validatePackageName() { + private String validatePackageName(boolean library) { String candidate = myPackageNameField.getText().trim(); if (candidate.length() == 0) { return AndroidBundle.message("specify.package.name.error"); @@ -87,6 +135,21 @@ public class AndroidAppPropertiesEditor { if (!AndroidCommonUtils.contains2Identifiers(candidate)) { return AndroidBundle.message("package.name.must.contain.2.ids.error"); } + + if (!library) { + for (Module module : myModulesProvider.getModules()) { + final AndroidFacet facet = AndroidFacet.getInstance(module); + if (facet != null && !facet.getConfiguration().LIBRARY_PROJECT) { + final Manifest manifest = facet.getManifest(); + if (manifest != null) { + final String packageName = manifest.getPackage().getValue(); + if (candidate.equals(packageName)) { + return "Package name '" + packageName + "' is already used by module '" + module.getName() + "'"; + } + } + } + } + } return ""; } @@ -122,12 +185,12 @@ public class AndroidAppPropertiesEditor { return myContentPanel; } - public void validate(boolean testProject) throws ConfigurationException { - String message = validatePackageName(); + public void validate(boolean library) throws ConfigurationException { + String message = validatePackageName(library); if (message.length() > 0) { throw new ConfigurationException(message); } - if (!testProject) { + if (!library) { message = validateActivityName(); if (message.length() > 0) { throw new ConfigurationException(message); @@ -147,15 +210,11 @@ public class AndroidAppPropertiesEditor { return myApplicationNameField.getText().trim(); } - public JCheckBox getHelloAndroidCheckBox() { - return myHelloAndroidCheckBox; - } - public JTextField getApplicationNameField() { return myApplicationNameField; } - public JPanel getActivtiyPanel() { - return myActivtiyPanel; + public JTextField getPackageNameField() { + return myPackageNameField; } } diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java index 454a5c1f5f07..d5b9b89a47db 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java @@ -199,23 +199,6 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { private boolean createProjectByAndroidTool(final VirtualFile contentRoot, final VirtualFile sourceRoot, final AndroidFacet facet) { - - - File tempContentRoot = null; - - // todo: support custom non-empty source root - - if (sourceRoot != null && - sourceRoot.getChildren().length == 0 && - (!Comparing.equal(sourceRoot.getParent(), contentRoot) || !SdkConstants.FD_SOURCES.equals(sourceRoot.getName()))) { - try { - tempContentRoot = FileUtil.createTempDirectory("android_temp_content_root", "tmp"); - } - catch (IOException e) { - LOG.error(e); - } - } - final Module module = facet.getModule(); AndroidPlatform platform = AndroidPlatform.parse(mySdk); @@ -254,7 +237,16 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { commandLine.addParameter(getAntProjectName(module.getName())); commandLine.addParameters("--path"); - final String targetDirectoryPath = tempContentRoot != null ? tempContentRoot.getPath() : contentRoot.getPath(); + + File tempContentRoot; + try { + tempContentRoot = FileUtil.createTempDirectory("android_temp_content_root", "tmp"); + } + catch (IOException e) { + LOG.error(e); + return false; + } + final String targetDirectoryPath = tempContentRoot.getPath(); commandLine.addParameter(FileUtil.toSystemDependentName(targetDirectoryPath)); if (myProjectType == ProjectType.APPLICATION || myProjectType == ProjectType.LIBRARY) { @@ -282,32 +274,12 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { @Override public void run() { final Project project = module.getProject(); - AndroidUtils.runExternalTool(commandLine, project); - - if (finalTempContentRoot != null) { - final File[] children = finalTempContentRoot.listFiles(); - - if (children != null) { - for (File child : children) { - if (SdkConstants.FD_SOURCES.equals(child.getName())) { - continue; - } - final File to = new File(contentRoot.getPath(), child.getName()); - - if (!FileUtil.moveDirWithContent(child, to)) { - LOG.error("Cannot move content from " + child.getPath() + " to " + to.getPath()); - } - } - } - - final File tempSourceRoot = new File(finalTempContentRoot, SdkConstants.FD_SOURCES); - if (tempSourceRoot.exists()) { - final File to = new File(sourceRoot.getPath()); - - if (!FileUtil.moveDirWithContent(tempSourceRoot, to)) { - LOG.error("Cannot move content from " + tempSourceRoot.getPath() + " to " + to.getPath()); - } - } + try { + AndroidUtils.runExternalTool(commandLine, project); + copyGeneratedAndroidProject(finalTempContentRoot, contentRoot, sourceRoot); + } + finally { + FileUtil.delete(finalTempContentRoot); } StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { @@ -387,6 +359,42 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { return true; } + private static void copyGeneratedAndroidProject(File tempDir, VirtualFile contentRoot, VirtualFile sourceRoot) { + final File[] children = tempDir.listFiles(); + if (children != null) { + for (File child : children) { + if (SdkConstants.FD_SOURCES.equals(child.getName())) { + continue; + } + final File to = new File(contentRoot.getPath(), child.getName()); + + try { + if (child.isDirectory()) { + FileUtil.copyDir(child, to); + } + else { + FileUtil.copy(child, to); + } + } + catch (IOException e) { + LOG.error(e); + } + } + } + + final File tempSourceRoot = new File(tempDir, SdkConstants.FD_SOURCES); + if (tempSourceRoot.exists()) { + final File to = new File(sourceRoot.getPath()); + + try { + FileUtil.copyDir(tempSourceRoot, to); + } + catch (IOException e) { + LOG.error(e); + } + } + } + private static void configureManifest(@NotNull AndroidFacet facet, @NotNull IAndroidTarget target) { final Manifest manifest = facet.getManifest(); if (manifest == null) { @@ -456,7 +464,8 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { AndroidPlatform platform = AndroidPlatform.parse(mySdk); if (platform == null) { - Messages.showErrorDialog(project, "Cannot parse Android SDK: 'default.properties' won't be generated", CommonBundle.getErrorTitle()); + Messages.showErrorDialog(project, "Cannot parse Android SDK: '" + SdkConstants.FN_PROJECT_PROPERTIES + "' won't be generated", + CommonBundle.getErrorTitle()); return; } @@ -672,7 +681,7 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { }); } - steps.add(new AndroidModuleWizardStep(this, wizardContext)); + steps.add(new AndroidModuleWizardStep(this, wizardContext, modulesProvider)); return steps.toArray(new ModuleWizardStep[steps.size()]); } diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleWizardStep.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleWizardStep.java index 31ab03089d17..9092b23c1807 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleWizardStep.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleWizardStep.java @@ -28,6 +28,7 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.ui.LabeledComponent; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; @@ -90,11 +91,11 @@ public class AndroidModuleWizardStep extends ModuleWizardStep { @NonNls private static final String TARGET_SELECTION_MODE_FOR_NEW_MODULE_PROPERTY = "ANDROID_TARGET_SELECTION_MODE_FOR_NEW_MODULE"; @NonNls private static final String TARGET_AVD_FOR_NEW_MODULE_PROPERTY = "ANDROID_TARGET_AVD_FOR_NEW_MODULE"; - public AndroidModuleWizardStep(@NotNull AndroidModuleBuilder moduleBuilder, WizardContext context) { + public AndroidModuleWizardStep(@NotNull AndroidModuleBuilder moduleBuilder, WizardContext context, ModulesProvider modulesProvider) { super(); myApplicationProjectButton.setSelected(true); - myAppPropertiesEditor = new AndroidAppPropertiesEditor(moduleBuilder.getName()); + myAppPropertiesEditor = new AndroidAppPropertiesEditor(moduleBuilder.getName(), modulesProvider); Project project = context.getProject(); myTestPropertiesEditor = project != null ? new AndroidTestPropertiesEditor(project) : null; myPropertiesPanel.setLayout(new OverlayLayout(myPropertiesPanel)); @@ -201,6 +202,7 @@ public class AndroidModuleWizardStep extends ModuleWizardStep { myDoNotCreateConfigurationRadioButton.setSelected(true); } } + updatePropertiesEditor(); } @Override @@ -223,15 +225,7 @@ public class AndroidModuleWizardStep extends ModuleWizardStep { if (myTestPropertiesEditor != null) { myTestPropertiesEditor.getContentPanel().setVisible(false); } - boolean app = myApplicationProjectButton.isSelected(); - myAppPropertiesEditor.getApplicationNameField().setEnabled(app); - myAppPropertiesEditor.getHelloAndroidCheckBox().setEnabled(app); - if (app) { - myAppPropertiesEditor.updateActivityPanel(); - } - else { - UIUtil.setEnabled(myAppPropertiesEditor.getActivtiyPanel(), app, true); - } + myAppPropertiesEditor.update(myApplicationProjectButton.isSelected()); } else { myAppPropertiesEditor.getContentPanel().setVisible(false); @@ -241,8 +235,12 @@ public class AndroidModuleWizardStep extends ModuleWizardStep { } public JComponent getComponent() { - myAppPropertiesEditor.getApplicationNameField().setText(myModuleBuilder.getName()); + final String moduleName = myModuleBuilder.getName(); + if (moduleName != null) { + myAppPropertiesEditor.getApplicationNameField().setText(moduleName); + myAppPropertiesEditor.getPackageNameField().setText(AndroidAppPropertiesEditor.getDefaultPackageNameByModuleName(moduleName)); + } Sdk selectedSdk = mySdkComboBoxWithBrowseButton.getSelectedSdk(); final PropertiesComponent properties = PropertiesComponent.getInstance(); @@ -281,7 +279,7 @@ public class AndroidModuleWizardStep extends ModuleWizardStep { } if (myApplicationProjectButton.isSelected() || myLibProjectButton.isSelected()) { - myAppPropertiesEditor.validate(myTestProjectButton.isSelected()); + myAppPropertiesEditor.validate(myLibProjectButton.isSelected()); } else { assert myTestPropertiesEditor != null; diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java index 8062411f4133..8294d4fc520c 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunningState.java @@ -53,6 +53,7 @@ import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.content.Content; import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.HashMap; import com.intellij.xdebugger.DefaultDebugProcessHandler; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.facet.AndroidRootUtil; @@ -69,7 +70,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -622,6 +623,7 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb message("Target device: " + getDevicePresentableName(device), STDOUT); try { if (myDeploy) { + if (!checkPackageNames()) return false; if (!uploadAndInstall(device, myPackageName, myFacet)) return false; if (!uploadAndInstallDependentModules(device)) return false; myApplicationDeployed = true; @@ -661,6 +663,45 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb return false; } } + + private boolean checkPackageNames() { + final Map> packageName2ModuleNames = new HashMap>(); + packageName2ModuleNames.put(myPackageName, new ArrayList(Arrays.asList(myFacet.getModule().getName()))); + + for (Map.Entry entry : myAdditionalFacet2PackageName.entrySet()) { + final String moduleName = entry.getKey().getModule().getName(); + final String packageName = entry.getValue(); + List list = packageName2ModuleNames.get(packageName); + + if (list == null) { + list = new ArrayList(); + packageName2ModuleNames.put(packageName, list); + } + list.add(moduleName); + } + boolean result = true; + + for (Map.Entry> entry : packageName2ModuleNames.entrySet()) { + final String packageName = entry.getKey(); + final List moduleNames = entry.getValue(); + + if (moduleNames.size() > 1) { + final StringBuilder messageBuilder = new StringBuilder("Applications have the same package name "); + messageBuilder.append(packageName).append(":\n "); + + for (Iterator it = moduleNames.iterator(); it.hasNext(); ) { + String moduleName = it.next(); + messageBuilder.append(moduleName); + if (it.hasNext()) { + messageBuilder.append(", "); + } + } + message(messageBuilder.toString(), STDERR); + result = false; + } + } + return result; + } protected static void clearLogcatAndConsole(@NotNull final Project project, @NotNull final IDevice device) { final boolean[] result = {true}; diff --git a/plugins/android/src/org/jetbrains/android/run/ExtendedDeviceChooserDialog.java b/plugins/android/src/org/jetbrains/android/run/ExtendedDeviceChooserDialog.java index 61a17ded1d1a..5cd03042bc56 100644 --- a/plugins/android/src/org/jetbrains/android/run/ExtendedDeviceChooserDialog.java +++ b/plugins/android/src/org/jetbrains/android/run/ExtendedDeviceChooserDialog.java @@ -95,6 +95,7 @@ public class ExtendedDeviceChooserDialog extends DialogWrapper { }; myLaunchEmulatorRadioButton.addActionListener(listener); myChooserRunningDeviceRadioButton.addActionListener(listener); + myAvdCombo.addActionListener(listener); init(); diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java index f54e4cf1afd5..15ce866737bc 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java @@ -806,4 +806,18 @@ public class AndroidResourceUtil { public static String getFieldNameByResourceName(@NotNull String fieldName) { return fieldName.replace('.', '_').replace('-', '_').replace(':', '_'); } + + @Nullable + public static String getInvalidResourceFileNameMessage(@NotNull String fileName) { + for (int i = 0, n = fileName.length(); i < n; i++) { + char c = fileName.charAt(i); + if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_' || c == '.')) { + return AndroidBundle.message("invalid.file.resource.name.error"); + } + } + if (!StringUtil.isJavaIdentifier(getFieldNameByResourceName(fileName))) { + return AndroidBundle.message("invalid.file.resource.name.error1"); + } + return null; + } } diff --git a/plugins/android/testData/dom/resources/nameValidation.xml b/plugins/android/testData/dom/resources/nameValidation.xml new file mode 100644 index 000000000000..acf5c477d4a6 --- /dev/null +++ b/plugins/android/testData/dom/resources/nameValidation.xml @@ -0,0 +1,9 @@ + + a + a + a + 1 + 1 + 1 + 1 + \ No newline at end of file diff --git a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidValueResourcesTest.java b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidValueResourcesTest.java index f504be57df66..0cba392db1f8 100644 --- a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidValueResourcesTest.java +++ b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidValueResourcesTest.java @@ -214,6 +214,10 @@ public class AndroidValueResourcesTest extends AndroidDomTest { doTestHighlighting(); } + public void testNameValidation() throws Throwable { + doTestHighlighting(); + } + public void testResourceReferenceAsValueCompletion1() throws Throwable { doTestCompletion(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java index ed5c200dac8c..0c485f1bfa63 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java @@ -1,176 +1,188 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.lang.completion; - -import com.intellij.codeInsight.completion.*; -import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; -import com.intellij.codeInsight.lookup.AutoCompletionPolicy; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.psi.*; -import com.intellij.psi.search.PsiShortNamesCache; -import com.intellij.util.Consumer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; - -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; - -/** - * @author peter - */ -public class GroovyNoVariantsDelegator extends CompletionContributor { - - @Override - public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { - final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(result.runRemainingContributors(parameters, true)); - - if (!empty && parameters.getInvocationCount() == 0) { - result.restartCompletionWhenNothingMatches(); - } - - if (empty) { - delegate(parameters, result); - } - } - - private static void delegate(CompletionParameters parameters, CompletionResultSet result) { - if (parameters.getCompletionType() == CompletionType.BASIC) { - if (parameters.getInvocationCount() <= 1 && - JavaCompletionContributor.mayStartClassName(result) && - GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) && - !MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) { - suggestNonImportedClasses(parameters, result); - } - - suggestChainedCalls(parameters, result); - } - } - - private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result) { - final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result); - - GroovyCompletionContributor.addAllClasses(parameters, new Consumer() { - @Override - public void consume(LookupElement element) { - JavaPsiClassReferenceElement classElement = - element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); - if (classElement != null) { - classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); - } - merger.consume(classElement); - } - }, new InheritorsHolder(parameters.getPosition(), result), result.getPrefixMatcher()); - - merger.finishedClassProcessing(); - } - - private static void suggestChainedCalls(CompletionParameters parameters, CompletionResultSet result) { - PsiElement position = parameters.getPosition(); - PsiElement parent = position.getParent(); - if (!(parent instanceof GrReferenceElement)) { - return; - } - PsiElement qualifier = ((GrReferenceElement)parent).getQualifier(); - if (!(qualifier instanceof GrReferenceElement) || - ((GrReferenceElement)qualifier).getQualifier() != null) { - return; - } - PsiElement target = ((GrReferenceElement)qualifier).resolve(); - if (target != null && !(target instanceof PsiPackage)) { - return; - } - - String fullPrefix = position.getContainingFile().getText().substring(parent.getTextRange().getStartOffset(), parameters.getOffset()); - final CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix); - InheritorsHolder inheritors = new InheritorsHolder(position, result); - for (final LookupElement base : suggestQualifierItems(parameters, (GrReferenceElement)qualifier, inheritors)) { - final PsiType type = JavaCompletionUtil.getLookupElementType(base); - if (type != null && !PsiType.VOID.equals(type)) { - GrReferenceElement ref = createMockReference(position, type, base); - PsiElement refName = ref.getReferenceNameElement(); - assert refName != null; - CompletionParameters newParams = parameters.withPosition(refName, refName.getTextRange().getStartOffset()); - GroovyCompletionContributor.completeReference(newParams, ref, inheritors, result.getPrefixMatcher(), new Consumer() { - @Override - public void consume(LookupElement element) { - qualifiedCollector.addElement(new JavaChainLookupElement(base, element) { - @Override - protected boolean shouldParenthesizeQualifier(PsiFile file, int startOffset, int endOffset) { - return false; - } - }); - } - }); - } - } - } - - private static GrReferenceElement createMockReference(final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) { - GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(place.getProject()); - if (qualifierItem.getObject() instanceof PsiClass) { - return factory - .createReferenceExpressionFromText(((PsiClass)qualifierItem.getObject()).getQualifiedName() + ".xxx", place); - } - - return factory.createReferenceExpressionFromText("xxx.xxx", - JavaCompletionUtil - .createContextWithXxxVariable(place, qualifierType)); - } - - - private static Set suggestQualifierItems(CompletionParameters _parameters, - GrReferenceElement qualifier, - InheritorsHolder inheritors) { - CompletionParameters parameters = - _parameters.withPosition(qualifier.getReferenceNameElement(), qualifier.getTextRange().getEndOffset()); - String referenceName = qualifier.getReferenceName(); - if (referenceName == null) { - return Collections.emptySet(); - } - - final PrefixMatcher qMatcher = new CamelHumpMatcher(referenceName); - final Set variants = new LinkedHashSet(); - GroovyCompletionContributor.completeReference(parameters, qualifier, inheritors, qMatcher, new Consumer() { - @Override - public void consume(LookupElement element) { - if (qMatcher.prefixMatches(element)) { - variants.add(element); - } - } - }); - - for (PsiClass aClass : PsiShortNamesCache.getInstance(qualifier.getProject()).getClassesByName(referenceName, qualifier.getResolveScope())) { - variants.add(GroovyCompletionUtil.createClassLookupItem(aClass)); - } - - - if (variants.isEmpty()) { - GroovyCompletionContributor.addAllClasses(parameters, new Consumer() { - @Override - public void consume(LookupElement element) { - if (qMatcher.prefixMatches(element)) { - variants.add(element); - } - } - }, inheritors, qMatcher); - } - return variants; - } - - -} +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.lang.completion; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; +import com.intellij.codeInsight.lookup.AutoCompletionPolicy; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.psi.*; +import com.intellij.psi.search.PsiShortNamesCache; +import com.intellij.util.Consumer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnnotationTypeDefinition; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import static com.intellij.patterns.PsiJavaPatterns.psiElement; + +/** + * @author peter + */ +public class GroovyNoVariantsDelegator extends CompletionContributor { + + private static boolean suggestMetaAnnotations(CompletionParameters parameters) { + PsiElement position = parameters.getPosition(); + return psiElement().withParents(GrCodeReferenceElement.class, GrAnnotation.class, GrModifierList.class, GrAnnotationTypeDefinition.class).accepts(position); + } + + @Override + public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { + final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(result.runRemainingContributors(parameters, true)) || + suggestMetaAnnotations(parameters); + + if (!empty && parameters.getInvocationCount() == 0) { + result.restartCompletionWhenNothingMatches(); + } + + if (empty) { + delegate(parameters, result); + } + } + + private static void delegate(CompletionParameters parameters, CompletionResultSet result) { + if (parameters.getCompletionType() == CompletionType.BASIC) { + if (parameters.getInvocationCount() <= 1 && + JavaCompletionContributor.mayStartClassName(result) && + GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) && + !MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) { + suggestNonImportedClasses(parameters, result); + } + + suggestChainedCalls(parameters, result); + } + } + + private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result) { + final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result); + + GroovyCompletionContributor.addAllClasses(parameters, new Consumer() { + @Override + public void consume(LookupElement element) { + JavaPsiClassReferenceElement classElement = + element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); + if (classElement != null) { + classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); + } + merger.consume(classElement); + } + }, new InheritorsHolder(parameters.getPosition(), result), result.getPrefixMatcher()); + + merger.finishedClassProcessing(); + } + + private static void suggestChainedCalls(CompletionParameters parameters, CompletionResultSet result) { + PsiElement position = parameters.getPosition(); + PsiElement parent = position.getParent(); + if (!(parent instanceof GrReferenceElement)) { + return; + } + PsiElement qualifier = ((GrReferenceElement)parent).getQualifier(); + if (!(qualifier instanceof GrReferenceElement) || + ((GrReferenceElement)qualifier).getQualifier() != null) { + return; + } + PsiElement target = ((GrReferenceElement)qualifier).resolve(); + if (target != null && !(target instanceof PsiPackage)) { + return; + } + + String fullPrefix = position.getContainingFile().getText().substring(parent.getTextRange().getStartOffset(), parameters.getOffset()); + final CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix); + InheritorsHolder inheritors = new InheritorsHolder(position, result); + for (final LookupElement base : suggestQualifierItems(parameters, (GrReferenceElement)qualifier, inheritors)) { + final PsiType type = JavaCompletionUtil.getLookupElementType(base); + if (type != null && !PsiType.VOID.equals(type)) { + GrReferenceElement ref = createMockReference(position, type, base); + PsiElement refName = ref.getReferenceNameElement(); + assert refName != null; + CompletionParameters newParams = parameters.withPosition(refName, refName.getTextRange().getStartOffset()); + GroovyCompletionContributor.completeReference(newParams, ref, inheritors, result.getPrefixMatcher(), new Consumer() { + @Override + public void consume(LookupElement element) { + qualifiedCollector.addElement(new JavaChainLookupElement(base, element) { + @Override + protected boolean shouldParenthesizeQualifier(PsiFile file, int startOffset, int endOffset) { + return false; + } + }); + } + }); + } + } + } + + private static GrReferenceElement createMockReference(final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) { + GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(place.getProject()); + if (qualifierItem.getObject() instanceof PsiClass) { + return factory + .createReferenceExpressionFromText(((PsiClass)qualifierItem.getObject()).getQualifiedName() + ".xxx", place); + } + + return factory.createReferenceExpressionFromText("xxx.xxx", + JavaCompletionUtil + .createContextWithXxxVariable(place, qualifierType)); + } + + + private static Set suggestQualifierItems(CompletionParameters _parameters, + GrReferenceElement qualifier, + InheritorsHolder inheritors) { + CompletionParameters parameters = + _parameters.withPosition(qualifier.getReferenceNameElement(), qualifier.getTextRange().getEndOffset()); + String referenceName = qualifier.getReferenceName(); + if (referenceName == null) { + return Collections.emptySet(); + } + + final PrefixMatcher qMatcher = new CamelHumpMatcher(referenceName); + final Set variants = new LinkedHashSet(); + GroovyCompletionContributor.completeReference(parameters, qualifier, inheritors, qMatcher, new Consumer() { + @Override + public void consume(LookupElement element) { + if (qMatcher.prefixMatches(element)) { + variants.add(element); + } + } + }); + + for (PsiClass aClass : PsiShortNamesCache.getInstance(qualifier.getProject()).getClassesByName(referenceName, qualifier.getResolveScope())) { + variants.add(GroovyCompletionUtil.createClassLookupItem(aClass)); + } + + + if (variants.isEmpty()) { + GroovyCompletionContributor.addAllClasses(parameters, new Consumer() { + @Override + public void consume(LookupElement element) { + if (qMatcher.prefixMatches(element)) { + variants.add(element); + } + } + }, inheritors, qMatcher); + } + return variants; + } + + +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java index 60fb62fa6cbb..36e6063a6ea0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java @@ -1,179 +1,190 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.lang.completion.weighers; - -import com.intellij.codeInsight.completion.CompletionLocation; -import com.intellij.codeInsight.completion.CompletionWeigher; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.PsiTypeLookupItem; -import com.intellij.psi.*; -import com.intellij.psi.impl.light.LightElement; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.containers.CollectionFactory; -import com.intellij.util.containers.hash.HashSet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; -import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionContributor; -import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; -import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; -import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrPropertyForCompletion; -import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; -import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; - -import java.util.Set; - -/** - * @author Maxim.Medvedev - */ -public class GrKindWeigher extends CompletionWeigher { - private static final Set TRASH_CLASSES = new HashSet(10); - private static final Set PRIORITY_KEYWORDS = CollectionFactory.hashSet( - PsiKeyword.RETURN, PsiKeyword.INSTANCEOF, "in", - PsiKeyword.PRIVATE, PsiKeyword.PROTECTED, PsiKeyword.PUBLIC, PsiKeyword.STATIC, "def", - PsiKeyword.TRUE, PsiKeyword.FALSE, PsiKeyword.NULL); - - static { - TRASH_CLASSES.add(CommonClassNames.JAVA_LANG_CLASS); - TRASH_CLASSES.add(CommonClassNames.JAVA_LANG_OBJECT); - TRASH_CLASSES.add(GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT); - } - - @Override - public Comparable weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) { - final PsiElement position = location.getCompletionParameters().getPosition(); - if (!(position.getContainingFile() instanceof GroovyFileBase)) return null; - - Object o = element.getObject(); - if (o instanceof ResolveResult) { - o = ((ResolveResult)o).getElement(); - } - - final PsiElement parent = position.getParent(); - final PsiElement qualifier = parent instanceof GrReferenceElement ? ((GrReferenceElement)parent).getQualifier() : null; - if (qualifier == null) { - if (o instanceof NamedArgumentDescriptor) { - switch (((NamedArgumentDescriptor)o).getPriority()) { - case ALWAYS_ON_TOP: - return NotQualifiedKind.onTop; - case AS_LOCAL_VARIABLE: - return NotQualifiedKind.local; - default: - return NotQualifiedKind.unknown; - } - } - if (o instanceof PsiVariable && !(o instanceof PsiField)) { - return NotQualifiedKind.local; - } - - PsiTypeLookupItem item = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY); - if (item != null && item.getBracketsCount() > 0) { - return NotQualifiedKind.arrayType; - } - - if (isPriorityKeyword(o)) return NotQualifiedKind.local; - if (isLightElement(o)) return NotQualifiedKind.unknown; - if (o instanceof PsiClass) { - if (((PsiClass)o).isAnnotationType() && GroovyCompletionContributor.AFTER_AT.accepts(position)) { - return NotQualifiedKind.restrictedClass; - } - if (GroovyCompletionContributor.IN_CATCH_TYPE.accepts(position) && - InheritanceUtil.isInheritor((PsiClass)o, CommonClassNames.JAVA_LANG_THROWABLE)) { - return NotQualifiedKind.restrictedClass; - } - } - if (o instanceof PsiMember) { - final PsiClass containingClass = ((PsiMember)o).getContainingClass(); - if (isAccessor((PsiMember)o)) return NotQualifiedKind.accessor; - if (o instanceof PsiClass && ((PsiClass)o).getContainingClass() == null || o instanceof PsiPackage) return NotQualifiedKind.unknown; - if (o instanceof PsiClass) return NotQualifiedKind.innerClass; - if (PsiTreeUtil.isContextAncestor(containingClass, position, false)) return NotQualifiedKind.currentClassMember; - return NotQualifiedKind.member; - } - return NotQualifiedKind.unknown; - } - else { - if (o instanceof PsiEnumConstant) return QualifiedKind.enumConstant; - - if (isLightElement(o)) return QualifiedKind.unknown; - if (o instanceof PsiMember) { - if (isTrashMethod((PsiMember)o)) return QualifiedKind.unknown; - if (isAccessor((PsiMember)o)) return QualifiedKind.accessor; - if (isQualifierClassMember((PsiMember)o, qualifier)) { - return QualifiedKind.currentClassMember; - } - if (o instanceof PsiClass && ((PsiClass)o).getContainingClass() == null || o instanceof PsiPackage) return QualifiedKind.unknown; - if (o instanceof PsiClass) return QualifiedKind.innerClass; - return QualifiedKind.member; - } - return QualifiedKind.unknown; - } - } - - private static boolean isPriorityKeyword(Object o) { - //noinspection SuspiciousMethodCalls - return PRIORITY_KEYWORDS.contains(o); - } - - private static boolean isLightElement(Object o) { - return o instanceof LightElement && !(o instanceof GrPropertyForCompletion) && !(o instanceof GrAccessorMethod); - } - - private static boolean isTrashMethod(PsiMember o) { - final PsiClass containingClass = o.getContainingClass(); - return containingClass != null && TRASH_CLASSES.contains(containingClass.getQualifiedName()); - } - - private static boolean isAccessor(PsiMember member) { - return member instanceof PsiMethod && (GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)member) || "setProperty".equals(((PsiMethod)member).getName())); - } - - - private static boolean isQualifierClassMember(PsiMember member, PsiElement qualifier) { - if (!(qualifier instanceof GrExpression)) return false; - - final PsiType type = ((GrExpression)qualifier).getType(); - if (!(type instanceof PsiClassType)) return false; - - final PsiClass psiClass = ((PsiClassType)type).resolve(); - if (psiClass == null) return false; - - return qualifier.getManager().areElementsEquivalent(member.getContainingClass(), psiClass); - } - - private enum NotQualifiedKind { - arrayType, - innerClass, - unknown, - accessor, - member, - currentClassMember, - restrictedClass, - local, - onTop - } - - private enum QualifiedKind { - innerClass, - unknown, - accessor, - member, - currentClassMember, - enumConstant, - } -} +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.lang.completion.weighers; + +import com.intellij.codeInsight.completion.CompletionLocation; +import com.intellij.codeInsight.completion.CompletionWeigher; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.PsiTypeLookupItem; +import com.intellij.psi.*; +import com.intellij.psi.impl.light.LightElement; +import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.CollectionFactory; +import com.intellij.util.containers.hash.HashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; +import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionContributor; +import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; +import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrPropertyForCompletion; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; + +import java.util.Set; + +/** + * @author Maxim.Medvedev + */ +public class GrKindWeigher extends CompletionWeigher { + private static final Set TRASH_CLASSES = new HashSet(10); + private static final Set PRIORITY_KEYWORDS = CollectionFactory.hashSet( + PsiKeyword.RETURN, PsiKeyword.INSTANCEOF, "in", + PsiKeyword.PRIVATE, PsiKeyword.PROTECTED, PsiKeyword.PUBLIC, PsiKeyword.STATIC, "def", + PsiKeyword.TRUE, PsiKeyword.FALSE, PsiKeyword.NULL); + + static { + TRASH_CLASSES.add(CommonClassNames.JAVA_LANG_CLASS); + TRASH_CLASSES.add(CommonClassNames.JAVA_LANG_OBJECT); + TRASH_CLASSES.add(GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT); + } + + @Override + public Comparable weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) { + final PsiElement position = location.getCompletionParameters().getPosition(); + if (!(position.getContainingFile() instanceof GroovyFileBase)) return null; + + Object o = element.getObject(); + if (o instanceof ResolveResult) { + o = ((ResolveResult)o).getElement(); + } + + final PsiElement parent = position.getParent(); + final PsiElement qualifier = parent instanceof GrReferenceElement ? ((GrReferenceElement)parent).getQualifier() : null; + if (qualifier == null) { + if (o instanceof NamedArgumentDescriptor) { + switch (((NamedArgumentDescriptor)o).getPriority()) { + case ALWAYS_ON_TOP: + return NotQualifiedKind.onTop; + case AS_LOCAL_VARIABLE: + return NotQualifiedKind.local; + default: + return NotQualifiedKind.unknown; + } + } + if (o instanceof PsiVariable && !(o instanceof PsiField)) { + return NotQualifiedKind.local; + } + + PsiTypeLookupItem item = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY); + if (item != null && item.getBracketsCount() > 0) { + return NotQualifiedKind.arrayType; + } + + if (isPriorityKeyword(o)) return NotQualifiedKind.local; + if (isLightElement(o)) return NotQualifiedKind.unknown; + if (o instanceof PsiClass) { + if (((PsiClass)o).isAnnotationType() && GroovyCompletionContributor.AFTER_AT.accepts(position)) { + final GrAnnotation annotation = PsiTreeUtil.getParentOfType(position, GrAnnotation.class); + if (annotation != null) { + PsiElement annoParent = annotation.getParent(); + PsiElement owner = annoParent.getParent(); + String[] elementTypeFields = GrAnnotationImpl.getApplicableElementTypeFields(annoParent instanceof PsiModifierList ? owner : annoParent); + if (PsiAnnotationImpl.isAnnotationApplicable(false, (PsiClass)o, elementTypeFields, position.getResolveScope())) { + return NotQualifiedKind.restrictedClass; + } + } + } + if (GroovyCompletionContributor.IN_CATCH_TYPE.accepts(position) && + InheritanceUtil.isInheritor((PsiClass)o, CommonClassNames.JAVA_LANG_THROWABLE)) { + return NotQualifiedKind.restrictedClass; + } + } + if (o instanceof PsiMember) { + final PsiClass containingClass = ((PsiMember)o).getContainingClass(); + if (isAccessor((PsiMember)o)) return NotQualifiedKind.accessor; + if (o instanceof PsiClass && ((PsiClass)o).getContainingClass() == null || o instanceof PsiPackage) return NotQualifiedKind.unknown; + if (o instanceof PsiClass) return NotQualifiedKind.innerClass; + if (PsiTreeUtil.isContextAncestor(containingClass, position, false)) return NotQualifiedKind.currentClassMember; + return NotQualifiedKind.member; + } + return NotQualifiedKind.unknown; + } + else { + if (o instanceof PsiEnumConstant) return QualifiedKind.enumConstant; + + if (isLightElement(o)) return QualifiedKind.unknown; + if (o instanceof PsiMember) { + if (isTrashMethod((PsiMember)o)) return QualifiedKind.unknown; + if (isAccessor((PsiMember)o)) return QualifiedKind.accessor; + if (isQualifierClassMember((PsiMember)o, qualifier)) { + return QualifiedKind.currentClassMember; + } + if (o instanceof PsiClass && ((PsiClass)o).getContainingClass() == null || o instanceof PsiPackage) return QualifiedKind.unknown; + if (o instanceof PsiClass) return QualifiedKind.innerClass; + return QualifiedKind.member; + } + return QualifiedKind.unknown; + } + } + + private static boolean isPriorityKeyword(Object o) { + //noinspection SuspiciousMethodCalls + return PRIORITY_KEYWORDS.contains(o); + } + + private static boolean isLightElement(Object o) { + return o instanceof LightElement && !(o instanceof GrPropertyForCompletion) && !(o instanceof GrAccessorMethod); + } + + private static boolean isTrashMethod(PsiMember o) { + final PsiClass containingClass = o.getContainingClass(); + return containingClass != null && TRASH_CLASSES.contains(containingClass.getQualifiedName()); + } + + private static boolean isAccessor(PsiMember member) { + return member instanceof PsiMethod && (GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)member) || "setProperty".equals(((PsiMethod)member).getName())); + } + + + private static boolean isQualifierClassMember(PsiMember member, PsiElement qualifier) { + if (!(qualifier instanceof GrExpression)) return false; + + final PsiType type = ((GrExpression)qualifier).getType(); + if (!(type instanceof PsiClassType)) return false; + + final PsiClass psiClass = ((PsiClassType)type).resolve(); + if (psiClass == null) return false; + + return qualifier.getManager().areElementsEquivalent(member.getContainingClass(), psiClass); + } + + private enum NotQualifiedKind { + arrayType, + innerClass, + unknown, + accessor, + member, + currentClassMember, + restrictedClass, + local, + onTop + } + + private enum QualifiedKind { + innerClass, + unknown, + accessor, + member, + currentClassMember, + enumConstant, + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java index fb954985066d..ddb032dfb9ef 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java @@ -179,7 +179,7 @@ public class GrAnnotationImpl extends GrStubElementBase implem GrCodeReferenceElement nameRef = annotation.getClassReference(); PsiElement resolved = nameRef.resolve(); if (resolved instanceof PsiClass && ((PsiClass)resolved).isAnnotationType()) { - return PsiAnnotationImpl.isAnnotationApplicable(strict, (PsiClass)resolved, elementTypeFields, annotation.getManager(),annotation.getResolveScope()); + return PsiAnnotationImpl.isAnnotationApplicable(strict, (PsiClass)resolved, elementTypeFields, annotation.getResolveScope()); } return !strict; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 57b3a07e1a30..1effb9ba323f 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -1398,4 +1398,20 @@ def bar(){}''') assertOrderedEquals(myFixture.lookupElementStrings, ['fooo', 'fooo1']) } + public void testPreferApplicableAnnotations() { + myFixture.addClass ''' +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ElementType.ANNOTATION_TYPE}) +@interface TMetaAnno {} + +@Target({ElementType.LOCAL_VARIABLE}) +@interface TLocalAnno {}''' + + configure('@T @interface Foo {}') + myFixture.completeBasic() + myFixture.assertPreferredCompletionItems 0, 'TMetaAnno', 'Target', 'TreeSelectionMode', 'TLocalAnno' + } + } \ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java index 5eee5a640775..a319b64bac20 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java @@ -1,246 +1,246 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.idea.maven.importing; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.roots.*; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.encoding.EncodingManager; -import com.intellij.pom.java.LanguageLevel; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.maven.model.MavenArtifact; -import org.jetbrains.idea.maven.model.MavenConstants; -import org.jetbrains.idea.maven.project.*; -import org.jetbrains.idea.maven.utils.MavenUtil; - -import java.nio.charset.Charset; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.UnsupportedCharsetException; -import java.util.List; -import java.util.Map; - -public class MavenModuleImporter { - private final Module myModule; - private final MavenProjectsTree myMavenTree; - private final MavenProject myMavenProject; - - @Nullable - private final MavenProjectChanges myMavenProjectChanges; - private final Map myMavenProjectToModuleName; - private final MavenImportingSettings mySettings; - private final MavenModifiableModelsProvider myModifiableModelsProvider; - private MavenRootModelAdapter myRootModelAdapter; - - public MavenModuleImporter(Module module, - MavenProjectsTree mavenTree, - MavenProject mavenProject, - @Nullable MavenProjectChanges changes, - Map mavenProjectToModuleName, - MavenImportingSettings settings, - MavenModifiableModelsProvider modifiableModelsProvider) { - myModule = module; - myMavenTree = mavenTree; - myMavenProject = mavenProject; - myMavenProjectChanges = changes; - myMavenProjectToModuleName = mavenProjectToModuleName; - mySettings = settings; - myModifiableModelsProvider = modifiableModelsProvider; - } - - public ModifiableRootModel getRootModel() { - return myRootModelAdapter.getRootModel(); - } - - public void config(boolean isNewlyCreatedModule) { - myRootModelAdapter = new MavenRootModelAdapter(myMavenProject, myModule, myModifiableModelsProvider); - myRootModelAdapter.init(isNewlyCreatedModule); - - configFolders(); - configDependencies(); - configLanguageLevel(); - configEncoding(); - } - - public void preConfigFacets() { - final ModuleType moduleType = ModuleType.get(myModule); - - for (final MavenImporter importer : getSuitableImporters()) { - final MavenProjectChanges changes; - if (myMavenProjectChanges == null) { - if (importer.processChangedModulesOnly()) continue; - changes = MavenProjectChanges.NONE; - } - else { - changes = myMavenProjectChanges; - } - - if (importer.getModuleType() == moduleType) { - // facets use FacetConfiguration and like that do not have modifiable models, - // therefore we have to take write lock - MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() { - public void run() { - importer.preProcess(myModule, myMavenProject, changes, myModifiableModelsProvider); - } - }); - } - } - } - - public void configFacets(final List postTasks) { - final ModuleType moduleType = ModuleType.get(myModule); - - for (final MavenImporter importer : getSuitableImporters()) { - final MavenProjectChanges changes; - if (myMavenProjectChanges == null) { - if (importer.processChangedModulesOnly()) continue; - changes = MavenProjectChanges.NONE; - } - else { - changes = myMavenProjectChanges; - } - - if (importer.getModuleType() == moduleType) { - // facets use FacetConfiguration and like that do not have modifiable models, - // therefore we have to take write lock - MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() { - public void run() { - importer.process(myModifiableModelsProvider, - myModule, - myRootModelAdapter, - myMavenTree, - myMavenProject, - changes, - myMavenProjectToModuleName, - postTasks); - } - }); - } - } - } - - private List getSuitableImporters() { - return myMavenProject.getSuitableImporters(); - } - - private void configFolders() { - new MavenFoldersImporter(myMavenProject, mySettings, myRootModelAdapter).config(); - } - - private void configDependencies() { - for (MavenArtifact artifact : myMavenProject.getDependencies()) { - if (!myMavenProject.isSupportedDependency(artifact, SupportedRequestType.FOR_IMPORT)) continue; - - DependencyScope scope = selectScope(artifact.getScope()); - MavenProject depProject = myMavenTree.findProject(artifact.getMavenId()); - - if (depProject != null) { - if (depProject == myMavenProject) continue; - myRootModelAdapter.addModuleDependency(myMavenProjectToModuleName.get(depProject), scope); - - Element buildHelperCfg = depProject.getPluginGoalConfiguration("org.codehaus.mojo", "build-helper-maven-plugin", "attach-artifact"); - if (buildHelperCfg != null) { - addAttachArtifactDependency(buildHelperCfg, scope, depProject, artifact); - } - } - else { - myRootModelAdapter.addLibraryDependency(artifact, scope, myModifiableModelsProvider, myMavenProject); - } - } - } - - private void addAttachArtifactDependency(@NotNull Element buildHelperCfg, - @NotNull DependencyScope scope, - @NotNull MavenProject mavenProject, - @NotNull MavenArtifact artifact) { - Library.ModifiableModel libraryModel = null; - - for (Element artifactsElement : (List)buildHelperCfg.getChildren("artifacts")) { - for (Element artifactElement : (List)artifactsElement.getChildren("artifact")) { - String typeString = artifactElement.getChildTextTrim("type"); - if (typeString != null && !typeString.equals("jar")) continue; - - OrderRootType rootType = OrderRootType.CLASSES; - - String classifier = artifactElement.getChildTextTrim("classifier"); - if ("sources".equals(classifier)) { - rootType = OrderRootType.SOURCES; - } - else if ("javadoc".equals(classifier)) { - rootType = JavadocOrderRootType.getInstance(); - } - - String filePath = artifactElement.getChildTextTrim("file"); - if (StringUtil.isEmpty(filePath)) continue; - - VirtualFile file = VfsUtil.findRelativeFile(filePath, mavenProject.getDirectoryFile()); - if (file == null) continue; - - file = JarFileSystem.getInstance().getJarRootForLocalFile(file); - if (file == null) continue; - - if (libraryModel == null) { - String libraryName = artifact.getLibraryName(); - assert libraryName.startsWith(MavenArtifact.MAVEN_LIB_PREFIX); - libraryName = MavenArtifact.MAVEN_LIB_PREFIX + "ATTACHED-JAR: " + libraryName.substring(MavenArtifact.MAVEN_LIB_PREFIX.length()); - - Library library = myModifiableModelsProvider.getLibraryByName(libraryName); - if (library == null) { - library = myModifiableModelsProvider.createLibrary(libraryName); - } - libraryModel = myModifiableModelsProvider.getLibraryModel(library); - - LibraryOrderEntry entry = myRootModelAdapter.getRootModel().addLibraryEntry(library); - entry.setScope(scope); - } - - libraryModel.addRoot(file, rootType); - } - } - } - - @NotNull - private static DependencyScope selectScope(String mavenScope) { - if (MavenConstants.SCOPE_RUNTIME.equals(mavenScope)) return DependencyScope.RUNTIME; - if (MavenConstants.SCOPE_TEST.equals(mavenScope)) return DependencyScope.TEST; - if (MavenConstants.SCOPE_PROVIDEED.equals(mavenScope)) return DependencyScope.PROVIDED; - return DependencyScope.COMPILE; - } - - private void configEncoding() { - if (Boolean.parseBoolean(System.getProperty("maven.disable.encode.import"))) return; - - String encoding = myMavenProject.getEncoding(); - if (encoding != null) { - try { - EncodingManager.getInstance().setEncoding(myMavenProject.getDirectoryFile(), Charset.forName(encoding)); - } - catch (UnsupportedCharsetException ignored) {/**/} - catch (IllegalCharsetNameException ignored) {/**/} - } - } - - private void configLanguageLevel() { - final LanguageLevel level = LanguageLevel.parse(myMavenProject.getSourceLevel()); - myRootModelAdapter.setLanguageLevel(level); - } -} +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.importing; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.encoding.EncodingProjectManager; +import com.intellij.pom.java.LanguageLevel; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.model.MavenArtifact; +import org.jetbrains.idea.maven.model.MavenConstants; +import org.jetbrains.idea.maven.project.*; +import org.jetbrains.idea.maven.utils.MavenUtil; + +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.util.List; +import java.util.Map; + +public class MavenModuleImporter { + private final Module myModule; + private final MavenProjectsTree myMavenTree; + private final MavenProject myMavenProject; + + @Nullable + private final MavenProjectChanges myMavenProjectChanges; + private final Map myMavenProjectToModuleName; + private final MavenImportingSettings mySettings; + private final MavenModifiableModelsProvider myModifiableModelsProvider; + private MavenRootModelAdapter myRootModelAdapter; + + public MavenModuleImporter(Module module, + MavenProjectsTree mavenTree, + MavenProject mavenProject, + @Nullable MavenProjectChanges changes, + Map mavenProjectToModuleName, + MavenImportingSettings settings, + MavenModifiableModelsProvider modifiableModelsProvider) { + myModule = module; + myMavenTree = mavenTree; + myMavenProject = mavenProject; + myMavenProjectChanges = changes; + myMavenProjectToModuleName = mavenProjectToModuleName; + mySettings = settings; + myModifiableModelsProvider = modifiableModelsProvider; + } + + public ModifiableRootModel getRootModel() { + return myRootModelAdapter.getRootModel(); + } + + public void config(boolean isNewlyCreatedModule) { + myRootModelAdapter = new MavenRootModelAdapter(myMavenProject, myModule, myModifiableModelsProvider); + myRootModelAdapter.init(isNewlyCreatedModule); + + configFolders(); + configDependencies(); + configLanguageLevel(); + configEncoding(); + } + + public void preConfigFacets() { + final ModuleType moduleType = ModuleType.get(myModule); + + for (final MavenImporter importer : getSuitableImporters()) { + final MavenProjectChanges changes; + if (myMavenProjectChanges == null) { + if (importer.processChangedModulesOnly()) continue; + changes = MavenProjectChanges.NONE; + } + else { + changes = myMavenProjectChanges; + } + + if (importer.getModuleType() == moduleType) { + // facets use FacetConfiguration and like that do not have modifiable models, + // therefore we have to take write lock + MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() { + public void run() { + importer.preProcess(myModule, myMavenProject, changes, myModifiableModelsProvider); + } + }); + } + } + } + + public void configFacets(final List postTasks) { + final ModuleType moduleType = ModuleType.get(myModule); + + for (final MavenImporter importer : getSuitableImporters()) { + final MavenProjectChanges changes; + if (myMavenProjectChanges == null) { + if (importer.processChangedModulesOnly()) continue; + changes = MavenProjectChanges.NONE; + } + else { + changes = myMavenProjectChanges; + } + + if (importer.getModuleType() == moduleType) { + // facets use FacetConfiguration and like that do not have modifiable models, + // therefore we have to take write lock + MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() { + public void run() { + importer.process(myModifiableModelsProvider, + myModule, + myRootModelAdapter, + myMavenTree, + myMavenProject, + changes, + myMavenProjectToModuleName, + postTasks); + } + }); + } + } + } + + private List getSuitableImporters() { + return myMavenProject.getSuitableImporters(); + } + + private void configFolders() { + new MavenFoldersImporter(myMavenProject, mySettings, myRootModelAdapter).config(); + } + + private void configDependencies() { + for (MavenArtifact artifact : myMavenProject.getDependencies()) { + if (!myMavenProject.isSupportedDependency(artifact, SupportedRequestType.FOR_IMPORT)) continue; + + DependencyScope scope = selectScope(artifact.getScope()); + MavenProject depProject = myMavenTree.findProject(artifact.getMavenId()); + + if (depProject != null) { + if (depProject == myMavenProject) continue; + myRootModelAdapter.addModuleDependency(myMavenProjectToModuleName.get(depProject), scope); + + Element buildHelperCfg = depProject.getPluginGoalConfiguration("org.codehaus.mojo", "build-helper-maven-plugin", "attach-artifact"); + if (buildHelperCfg != null) { + addAttachArtifactDependency(buildHelperCfg, scope, depProject, artifact); + } + } + else { + myRootModelAdapter.addLibraryDependency(artifact, scope, myModifiableModelsProvider, myMavenProject); + } + } + } + + private void addAttachArtifactDependency(@NotNull Element buildHelperCfg, + @NotNull DependencyScope scope, + @NotNull MavenProject mavenProject, + @NotNull MavenArtifact artifact) { + Library.ModifiableModel libraryModel = null; + + for (Element artifactsElement : (List)buildHelperCfg.getChildren("artifacts")) { + for (Element artifactElement : (List)artifactsElement.getChildren("artifact")) { + String typeString = artifactElement.getChildTextTrim("type"); + if (typeString != null && !typeString.equals("jar")) continue; + + OrderRootType rootType = OrderRootType.CLASSES; + + String classifier = artifactElement.getChildTextTrim("classifier"); + if ("sources".equals(classifier)) { + rootType = OrderRootType.SOURCES; + } + else if ("javadoc".equals(classifier)) { + rootType = JavadocOrderRootType.getInstance(); + } + + String filePath = artifactElement.getChildTextTrim("file"); + if (StringUtil.isEmpty(filePath)) continue; + + VirtualFile file = VfsUtil.findRelativeFile(filePath, mavenProject.getDirectoryFile()); + if (file == null) continue; + + file = JarFileSystem.getInstance().getJarRootForLocalFile(file); + if (file == null) continue; + + if (libraryModel == null) { + String libraryName = artifact.getLibraryName(); + assert libraryName.startsWith(MavenArtifact.MAVEN_LIB_PREFIX); + libraryName = MavenArtifact.MAVEN_LIB_PREFIX + "ATTACHED-JAR: " + libraryName.substring(MavenArtifact.MAVEN_LIB_PREFIX.length()); + + Library library = myModifiableModelsProvider.getLibraryByName(libraryName); + if (library == null) { + library = myModifiableModelsProvider.createLibrary(libraryName); + } + libraryModel = myModifiableModelsProvider.getLibraryModel(library); + + LibraryOrderEntry entry = myRootModelAdapter.getRootModel().addLibraryEntry(library); + entry.setScope(scope); + } + + libraryModel.addRoot(file, rootType); + } + } + } + + @NotNull + private static DependencyScope selectScope(String mavenScope) { + if (MavenConstants.SCOPE_RUNTIME.equals(mavenScope)) return DependencyScope.RUNTIME; + if (MavenConstants.SCOPE_TEST.equals(mavenScope)) return DependencyScope.TEST; + if (MavenConstants.SCOPE_PROVIDEED.equals(mavenScope)) return DependencyScope.PROVIDED; + return DependencyScope.COMPILE; + } + + private void configEncoding() { + if (Boolean.parseBoolean(System.getProperty("maven.disable.encode.import"))) return; + + String encoding = myMavenProject.getEncoding(); + if (encoding != null) { + try { + EncodingProjectManager.getInstance(myModule.getProject()).setEncoding(myMavenProject.getDirectoryFile(), Charset.forName(encoding)); + } + catch (UnsupportedCharsetException ignored) {/**/} + catch (IllegalCharsetNameException ignored) {/**/} + } + } + + private void configLanguageLevel() { + final LanguageLevel level = LanguageLevel.parse(myMavenProject.getSourceLevel()); + myRootModelAdapter.setLanguageLevel(level); + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleNameMapper.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleNameMapper.java index c125e65db08e..877fd771e545 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleNameMapper.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleNameMapper.java @@ -102,7 +102,7 @@ public class MavenModuleNameMapper { mavenProjectToModuleName.put(each.project, each.getResultName()); } - assert new HashSet(mavenProjectToModuleName.values()).size() == mavenProjectToModuleName.size(); + assert new HashSet(mavenProjectToModuleName.values()).size() == mavenProjectToModuleName.size() : mavenProjectToModuleName; } public static class NameItem implements Comparable { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenNavigationUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenNavigationUtil.java index c78438e07754..0d665347ae29 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenNavigationUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenNavigationUtil.java @@ -72,6 +72,8 @@ public class MavenNavigationUtil { public static Navigatable createNavigatableForDependency(final Project project, final VirtualFile file, final MavenArtifact artifact) { return new NavigatableAdapter() { public void navigate(boolean requestFocus) { + if (!file.isValid()) return; + final PsiFile pom = PsiManager.getInstance(project).findFile(file); if (pom instanceof XmlFile) { final XmlTag id = findDependency((XmlFile)pom, artifact.getArtifactId()); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java index 4cea7a342eb8..c566f537d32c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.maven.project; import com.intellij.ide.startup.StartupManagerEx; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.components.*; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; @@ -334,10 +335,21 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent if (shouldScheduleProject(projectWithChanges)) { scheduleForNextImport(projectWithChanges); + MavenImportingSettings importingSettings; + + AccessToken token = ReadAction.start(); + try { + if (myProject.isDisposed()) return; + importingSettings = getImportingSettings(); + } + finally { + token.finish(); + } + scheduleArtifactsDownloading(Collections.singleton(projectWithChanges.first), null, - getImportingSettings().isDownloadSourcesAutomatically(), - getImportingSettings().isDownloadDocsAutomatically(), + importingSettings.isDownloadSourcesAutomatically(), + importingSettings.isDownloadDocsAutomatically(), null); } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java index 4e282fabea6c..133a3af9e2d8 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java @@ -26,6 +26,16 @@ import org.jetbrains.idea.maven.importing.MavenDefaultModifiableModelsProvider; import org.jetbrains.idea.maven.importing.MavenRootModelAdapter; public class ResourceCopyingTest extends MavenImportingTestCase { + + @Override + protected void setUpInWriteAction() throws Exception { + super.setUpInWriteAction(); + + CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.xxx"); + CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.yyy"); + CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.zzz"); + } + public void testBasic() throws Exception { createProjectSubFile("src/main/resources/dir/file.properties"); diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java index f7e30de3c33f..aabc01b98742 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java @@ -368,9 +368,15 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn public void run() { animator.stopMovie(); updateStatusLine(); - if (total > count) { + if (total > count || myStatus == MessageHelper.SKIPPED_TEST) { myStatusLine.setStatusColor(ColorProgressBar.YELLOW); } + else if (myStatus == MessageHelper.FAILED_TEST) { + myStatusLine.setStatusColor(ColorProgressBar.RED); + } + else { + myStatusLine.setStatusColor(ColorProgressBar.GREEN); + } rootNode.setInProgress(false); if (TestNGConsoleProperties.SELECT_FIRST_DEFECT.value(myProperties)) { selectTest(rootNode.getFirstDefect()); diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 5cc31d889e58..df858b547c50 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -764,7 +764,8 @@ - + +