@Override public void addEntryPoint(@NotNull RefElement newEntryPoint, boolean isPersistent) { if (!newEntryPoint.isValid()) return; if (isPersistent) { if (newEntryPoint instanceof RefMethod && ((RefMethod) newEntryPoint).isConstructor() || newEntryPoint instanceof RefClass) { final ClassPattern classPattern = new ClassPattern(); classPattern.pattern = new SmartRefElementPointerImpl(newEntryPoint, true).getFQName(); getPatterns().add(classPattern); final EntryPointsManager entryPointsManager = getInstance(newEntryPoint.getElement().getProject()); if (this != entryPointsManager) { entryPointsManager.addEntryPoint(newEntryPoint, true); } return; } } if (newEntryPoint instanceof RefClass) { RefClass refClass = (RefClass) newEntryPoint; if (refClass.isAnonymous()) { // Anonymous class cannot be an entry point. return; } List<RefMethod> refConstructors = refClass.getConstructors(); if (refConstructors.size() == 1) { addEntryPoint(refConstructors.get(0), isPersistent); } else if (refConstructors.size() > 1) { // Many constructors here. Need to ask user which ones are used for (RefMethod refConstructor : refConstructors) { addEntryPoint(refConstructor, isPersistent); } } } if (!isPersistent) { myTemporaryEntryPoints.add(newEntryPoint); ((RefElementImpl) newEntryPoint).setEntry(true); } else { if (myPersistentEntryPoints.get(newEntryPoint.getExternalName()) == null) { final SmartRefElementPointerImpl entry = new SmartRefElementPointerImpl(newEntryPoint, true); myPersistentEntryPoints.put(entry.getFQName(), entry); ((RefElementImpl) newEntryPoint).setEntry(true); ((RefElementImpl) newEntryPoint).setPermanentEntry(true); if (entry.isPersistent()) { // do save entry points final EntryPointsManager entryPointsManager = getInstance(newEntryPoint.getElement().getProject()); if (this != entryPointsManager) { entryPointsManager.addEntryPoint(newEntryPoint, true); } } } } }
@Override public void resolveEntryPoints(@NotNull final RefManager manager) { if (!myResolved) { myResolved = true; cleanup(); validateEntryPoints(); ApplicationManager.getApplication() .runReadAction( () -> { for (SmartRefElementPointer entryPoint : myPersistentEntryPoints.values()) { if (entryPoint.resolve(manager)) { RefEntity refElement = entryPoint.getRefElement(); ((RefElementImpl) refElement).setEntry(true); ((RefElementImpl) refElement).setPermanentEntry(entryPoint.isPersistent()); } } for (ClassPattern pattern : myPatterns) { final RefEntity refClass = manager.getReference(RefJavaManager.CLASS, pattern.pattern); if (refClass != null) { for (RefMethod constructor : ((RefClass) refClass).getConstructors()) { ((RefMethodImpl) constructor).setEntry(true); ((RefMethodImpl) constructor).setPermanentEntry(true); } } } }); } }
@Override @SuppressWarnings({"HardCodedStringLiteral"}) public void loadState(Element element) { Element entryPointsElement = element.getChild("entry_points"); if (entryPointsElement != null) { final String version = entryPointsElement.getAttributeValue(VERSION_ATTR); if (!Comparing.strEqual(version, VERSION)) { convert(entryPointsElement, myPersistentEntryPoints); } else { List content = entryPointsElement.getChildren(); for (final Object aContent : content) { Element entryElement = (Element) aContent; if (ENTRY_POINT_ATTR.equals(entryElement.getName())) { SmartRefElementPointerImpl entryPoint = new SmartRefElementPointerImpl(entryElement); myPersistentEntryPoints.put(entryPoint.getFQName(), entryPoint); } } } } try { ADDITIONAL_ANNOTATIONS.readExternal(element); } catch (Throwable ignored) { } getPatterns().clear(); for (Element pattern : element.getChildren("pattern")) { final ClassPattern classPattern = new ClassPattern(); XmlSerializer.deserializeInto(classPattern, pattern); getPatterns().add(classPattern); } }
@Override public void cleanup() { purgeTemporaryEntryPoints(); Collection<SmartRefElementPointer> entries = myPersistentEntryPoints.values(); for (SmartRefElementPointer entry : entries) { entry.freeReference(); } }
@Override public void removeEntryPoint(@NotNull RefElement anEntryPoint) { myTemporaryEntryPoints.remove(anEntryPoint); Set<Map.Entry<String, SmartRefElementPointer>> set = myPersistentEntryPoints.entrySet(); String key = null; for (Map.Entry<String, SmartRefElementPointer> entry : set) { SmartRefElementPointer value = entry.getValue(); if (value.getRefElement() == anEntryPoint) { key = entry.getKey(); break; } } if (key != null) { myPersistentEntryPoints.remove(key); } ((RefElementImpl) anEntryPoint).setEntry(false); if (anEntryPoint.isPermanentEntry() && anEntryPoint.isValid()) { final Project project = anEntryPoint.getElement().getProject(); final EntryPointsManager entryPointsManager = getInstance(project); if (this != entryPointsManager) { entryPointsManager.removeEntryPoint(anEntryPoint); } } if (anEntryPoint instanceof RefMethod && ((RefMethod) anEntryPoint).isConstructor() || anEntryPoint instanceof RefClass) { final RefClass aClass = anEntryPoint instanceof RefClass ? (RefClass) anEntryPoint : ((RefMethod) anEntryPoint).getOwnerClass(); final String qualifiedName = aClass.getQualifiedName(); for (Iterator<ClassPattern> iterator = getPatterns().iterator(); iterator.hasNext(); ) { if (Comparing.equal(iterator.next().pattern, qualifiedName)) { // todo if inheritance or pattern? iterator.remove(); } } } }
private void validateEntryPoints() { long count = PsiManager.getInstance(myProject).getModificationTracker().getModificationCount(); if (count != myLastModificationCount) { myLastModificationCount = count; Collection<SmartRefElementPointer> collection = myPersistentEntryPoints.values(); SmartRefElementPointer[] entries = collection.toArray(new SmartRefElementPointer[collection.size()]); for (SmartRefElementPointer entry : entries) { RefElement refElement = (RefElement) entry.getRefElement(); if (refElement != null && !refElement.isValid()) { myPersistentEntryPoints.remove(entry.getFQName()); } } final Iterator<RefElement> it = myTemporaryEntryPoints.iterator(); while (it.hasNext()) { RefElement refElement = it.next(); if (!refElement.isValid()) { it.remove(); } } } }
@NotNull @Override public RefElement[] getEntryPoints() { validateEntryPoints(); List<RefElement> entries = new ArrayList<RefElement>(); Collection<SmartRefElementPointer> collection = myPersistentEntryPoints.values(); for (SmartRefElementPointer refElementPointer : collection) { final RefEntity elt = refElementPointer.getRefElement(); if (elt instanceof RefElement) { entries.add((RefElement) elt); } } entries.addAll(myTemporaryEntryPoints); return entries.toArray(new RefElement[entries.size()]); }
@SuppressWarnings({"HardCodedStringLiteral"}) public static void writeExternal( final Element element, final Map<String, SmartRefElementPointer> persistentEntryPoints, final JDOMExternalizableStringList additional_annotations) { Element entryPointsElement = new Element("entry_points"); entryPointsElement.setAttribute(VERSION_ATTR, VERSION); for (SmartRefElementPointer entryPoint : persistentEntryPoints.values()) { assert entryPoint.isPersistent(); entryPoint.writeExternal(entryPointsElement); } element.addContent(entryPointsElement); if (!additional_annotations.isEmpty()) { additional_annotations.writeExternal(element); } }
public static void convert( Element element, final Map<String, SmartRefElementPointer> persistentEntryPoints) { List content = element.getChildren(); for (final Object aContent : content) { Element entryElement = (Element) aContent; if (ENTRY_POINT_ATTR.equals(entryElement.getName())) { String fqName = entryElement.getAttributeValue(SmartRefElementPointerImpl.FQNAME_ATTR); final String type = entryElement.getAttributeValue(SmartRefElementPointerImpl.TYPE_ATTR); if (Comparing.strEqual(type, RefJavaManager.METHOD)) { int spaceIdx = fqName.indexOf(' '); int lastDotIdx = fqName.lastIndexOf('.'); int parenIndex = fqName.indexOf('('); while (lastDotIdx > parenIndex) lastDotIdx = fqName.lastIndexOf('.', lastDotIdx - 1); boolean notype = false; if (spaceIdx < 0 || spaceIdx + 1 > lastDotIdx || spaceIdx > parenIndex) { notype = true; } final String className = fqName.substring(notype ? 0 : spaceIdx + 1, lastDotIdx); final String methodSignature = notype ? fqName.substring(lastDotIdx + 1) : fqName.substring(0, spaceIdx) + ' ' + fqName.substring(lastDotIdx + 1); fqName = className + " " + methodSignature; } else if (Comparing.strEqual(type, RefJavaManager.FIELD)) { final int lastDotIdx = fqName.lastIndexOf('.'); if (lastDotIdx > 0 && lastDotIdx < fqName.length() - 2) { String className = fqName.substring(0, lastDotIdx); String fieldName = fqName.substring(lastDotIdx + 1); fqName = className + " " + fieldName; } else { continue; } } SmartRefElementPointerImpl entryPoint = new SmartRefElementPointerImpl(type, fqName); persistentEntryPoints.put(entryPoint.getFQName(), entryPoint); } } }
public void addAllPersistentEntries(EntryPointsManagerBase manager) { myPersistentEntryPoints.putAll(manager.myPersistentEntryPoints); myPatterns.addAll(manager.getPatterns()); }