This commit is contained in:
Alexey Kudravtsev
2012-03-19 13:09:38 +04:00
parent b60202e290
commit d3d5ef6ed6
@@ -79,14 +79,13 @@ import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
@NotNull public static final Icon ICON = IconLoader.getIcon("/modules/annotation.png");
private static final Logger LOG = Logger.getInstance("#" + ExternalAnnotationsManagerImpl.class.getName());
@NotNull private final ConcurrentMap<String, List<XmlFile>> myExternalAnnotations = new ConcurrentWeakValueHashMap<String, List<XmlFile>>();
@NotNull private final AtomicReference<ThreeState> myHasAnyAnnotationsRoots = new AtomicReference<ThreeState>(ThreeState.UNSURE);
@NotNull private volatile ThreeState myHasAnyAnnotationsRoots = ThreeState.UNSURE;
@NotNull private static final List<XmlFile> NULL = new ArrayList<XmlFile>();
private final PsiManager myPsiManager;
@@ -94,38 +93,42 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
myPsiManager = psiManager;
final MessageBusConnection connection = project.getMessageBus().connect(project);
connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
@Override
public void beforeRootsChange(ModuleRootEvent event) {
}
@Override
public void rootsChanged(ModuleRootEvent event) {
myExternalAnnotations.clear();
myHasAnyAnnotationsRoots.set(ThreeState.UNSURE);
myHasAnyAnnotationsRoots = ThreeState.UNSURE;
}
});
}
private ThreeState hasAnyAnnotationsRoots() {
if (myHasAnyAnnotationsRoots.get() == ThreeState.UNSURE) {
if (myHasAnyAnnotationsRoots == ThreeState.UNSURE) {
final Module[] modules = ModuleManager.getInstance(myPsiManager.getProject()).getModules();
for (Module module : modules) {
for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
final String[] urls = AnnotationOrderRootType.getUrls(entry);
if (urls.length > 0) {
myHasAnyAnnotationsRoots.set(ThreeState.YES);
myHasAnyAnnotationsRoots = ThreeState.YES;
return ThreeState.YES;
}
}
}
myHasAnyAnnotationsRoots.set(ThreeState.NO);
myHasAnyAnnotationsRoots = ThreeState.NO;
}
return myHasAnyAnnotationsRoots.get();
return myHasAnyAnnotationsRoots;
}
@Override
@Nullable
public PsiAnnotation findExternalAnnotation(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN) {
return collectExternalAnnotations(listOwner).get(annotationFQN);
}
@Override
@Nullable
public PsiAnnotation[] findExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) {
final Map<String, PsiAnnotation> result = collectExternalAnnotations(listOwner);
@@ -135,11 +138,11 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
@NotNull
private Map<String, PsiAnnotation> collectExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) {
if (hasAnyAnnotationsRoots() == ThreeState.NO) return Collections.emptyMap();
final Map<String, PsiAnnotation> result = new HashMap<String, PsiAnnotation>();
final List<XmlFile> files = findExternalAnnotationsFile(listOwner);
final List<XmlFile> files = findExternalAnnotationsFiles(listOwner);
if (files == null) {
return Collections.emptyMap();
}
final Map<String, PsiAnnotation> result = new HashMap<String, PsiAnnotation>();
for (XmlFile file : files) {
if (!file.isValid()) continue;
final XmlDocument document = file.getDocument();
@@ -168,7 +171,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
"@" + annotationFQN + (buf.length() > 0 ? "(" + StringUtil.trimStart(buf.toString(), ",") + ")" : "");
try {
result.put(annotationFQN,
JavaPsiFacade.getInstance(listOwner.getProject()).getElementFactory().createAnnotationFromText(
JavaPsiFacade.getInstance(myPsiManager.getProject()).getElementFactory().createAnnotationFromText(
annotationText, null));
}
catch (IncorrectOperationException e) {
@@ -186,11 +189,12 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
}
@Override
public void annotateExternally(@NotNull final PsiModifierListOwner listOwner,
@NotNull final String annotationFQName,
@NotNull final PsiFile fromFile,
final PsiNameValuePair[] value) {
final Project project = listOwner.getProject();
final Project project = myPsiManager.getProject();
final PsiFile containingFile = listOwner.getContainingFile();
if (!(containingFile instanceof PsiJavaFile)) {
return;
@@ -215,6 +219,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
return;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setupRootAndAnnotateExternally(entry, project, listOwner, annotationFQName, fromFile, packageName, virtualFile, value);
}
@@ -240,9 +245,10 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
return;
}
new WriteCommandAction(project) {
@Override
protected void run(final Result result) throws Throwable {
appendChosenAnnotationsRoot(entry, file);
final List<XmlFile> xmlFiles = findExternalAnnotationsFile(listOwner);
final List<XmlFile> xmlFiles = findExternalAnnotationsFiles(listOwner);
if (xmlFiles != null) { //file already exists under appeared content root
if (!CodeInsightUtilBase.preparePsiElementForWrite(xmlFiles.get(0))) return;
annotateExternally(listOwner, annotationFQName, xmlFiles.get(0), fromFile, value);
@@ -314,7 +320,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
@NotNull final PsiFile fromFile,
final PsiNameValuePair[] value) {
final XmlFile[] annotationsXml = new XmlFile[1];
List<XmlFile> xmlFiles = findExternalAnnotationsFile(listOwner);
List<XmlFile> xmlFiles = findExternalAnnotationsFiles(listOwner);
if (xmlFiles != null) {
for (XmlFile xmlFile : xmlFiles) {
final VirtualFile vXmlFile = xmlFile.getVirtualFile();
@@ -330,6 +336,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
final List<XmlFile> annotationFiles = new ArrayList<XmlFile>(xmlFiles);
new WriteCommandAction(project) {
@Override
protected void run(final Result result) throws Throwable {
if (annotationsXml[0] == null) {
annotationsXml[0] = createAnnotationsXml(file, packageName);
@@ -343,8 +350,9 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
}.execute();
}
@Override
public boolean deannotate(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN) {
final List<XmlFile> files = findExternalAnnotationsFile(listOwner);
final List<XmlFile> files = findExternalAnnotationsFiles(listOwner);
if (files != null) {
for (XmlFile file : files) {
if (file.isValid()) {
@@ -359,7 +367,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
if (Comparing.strEqual(className, externalName) || Comparing.strEqual(className, oldExternalName)) {
for (XmlTag annotationTag : tag.getSubTags()) {
if (Comparing.strEqual(annotationTag.getAttributeValue("name"), annotationFQN)) {
if (ReadonlyStatusHandler.getInstance(file.getProject())
if (ReadonlyStatusHandler.getInstance(myPsiManager.getProject())
.ensureFilesWritable(file.getVirtualFile()).hasReadonlyFiles()) {
return false;
}
@@ -386,11 +394,12 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
return false;
}
@Override
@NotNull
public AnnotationPlace chooseAnnotationsPlace(@NotNull final PsiElement element) {
if (!element.isPhysical()) return AnnotationPlace.IN_CODE; //element just created
if (!element.getManager().isInProject(element)) return AnnotationPlace.EXTERNAL;
final Project project = element.getProject();
final Project project = myPsiManager.getProject();
final PsiFile containingFile = element.getContainingFile();
final VirtualFile virtualFile = containingFile.getVirtualFile();
LOG.assertTrue(virtualFile != null);
@@ -472,7 +481,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
myExternalAnnotations.clear();
}
private static void annotateExternally(final PsiModifierListOwner listOwner,
private void annotateExternally(final PsiModifierListOwner listOwner,
final String annotationFQName,
@Nullable final XmlFile xmlFile,
@NotNull PsiFile codeUsageFile,
@@ -492,7 +501,8 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
break;
}
}
tag.add(XmlElementFactory.getInstance(xmlFile.getProject()).createTagFromText(createAnnotationTag(annotationFQName, values)));
tag.add(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(
createAnnotationTag(annotationFQName, values)));
return;
}
}
@@ -500,7 +510,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
"<item name=\'" + externalName + "\'>\n";
text += createAnnotationTag(annotationFQName, values);
text += "</item>";
rootTag.add(XmlElementFactory.getInstance(xmlFile.getProject()).createTagFromText(text));
rootTag.add(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(text));
}
}
}
@@ -520,13 +530,13 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
if (values != null) {
text = " <annotation name=\'" + annotationFQName + "\'>\n";
text += StringUtil.join(values, new Function<PsiNameValuePair, String>() {
@NonNls
@NotNull
@Override
public String fun(@NotNull PsiNameValuePair pair) {
if (pair.getName() != null) {
return "<val name=\"" + pair.getName() + "\" val=\"" + StringUtil.escapeXml(pair.getValue().getText()) + "\"/>";
}
return "<val val=\"" + StringUtil.escapeXml(pair.getValue().getText()) + "\"/>";
return "<val" +
(pair.getName() != null ? " name=\"" + pair.getName() + "\"" : "") +
" val=\"" + StringUtil.escapeXml(pair.getValue().getText()) + "\"/>";
}
}, " \n");
text += " </annotation>";
@@ -572,8 +582,8 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
}
@Nullable
private List<XmlFile> findExternalAnnotationsFile(@NotNull PsiModifierListOwner listOwner) {
final Project project = listOwner.getProject();
private List<XmlFile> findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) {
final Project project = myPsiManager.getProject();
final PsiFile containingFile = listOwner.getContainingFile();
if (!(containingFile instanceof PsiJavaFile)) {
return null;
@@ -672,15 +682,18 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
init();
}
@Override
protected String getOkActionName() {
return ADD_IN_CODE;
}
@Override
@NotNull
protected String getCancelActionName() {
return CommonBundle.getCancelButtonText();
}
@Override
@NotNull
@SuppressWarnings({"NonStaticInitializer"})
protected Action[] createActions() {
@@ -692,6 +705,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
assignMnemonic(externalName, this);
}
@Override
public void actionPerformed(final ActionEvent e) {
if (canBeHidden()) {
setToBeShown(toBeShown(), true);
@@ -701,20 +715,24 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
}, getCancelAction()};
}
@Override
protected boolean isToBeShown() {
return CodeStyleSettingsManager.getSettings(myProject).USE_EXTERNAL_ANNOTATIONS;
}
@Override
protected void setToBeShown(boolean value, boolean onOk) {
CodeStyleSettingsManager.getSettings(myProject).USE_EXTERNAL_ANNOTATIONS = value;
}
@Override
protected JComponent createNorthPanel() {
final JPanel northPanel = (JPanel)super.createNorthPanel();
northPanel.add(new JLabel(MESSAGE), BorderLayout.CENTER);
return northPanel;
}
@Override
protected boolean shouldSaveOptionsOnCancel() {
return true;
}