Permalink
Browse files

Reuse structure of externals and OTP using proxies in the model tree

  • Loading branch information...
1 parent 4fb58c2 commit 176548844d90ec620fed3dd733106b422290f413 @jakobc jakobc committed Mar 7, 2013
@@ -0,0 +1,20 @@
+/**
+ *
+ */
+package org.erlide.model.root;
+
+import java.util.List;
+
+import org.erlide.model.IOpenable;
+import org.erlide.model.IParent;
+
+/**
+ * @author jakob
+ *
+ */
+public interface IErlExternalRoot extends IErlExternal, IErlElement, IParent,
+ IOpenable {
+
+ List<IErlElement> internalGetChildren();
+
+}
@@ -153,8 +153,8 @@ void addElementChangedListener(IElementChangedListener listener,
void registerModelDelta(IErlElementDelta delta);
- IErlModule getModuleFromFile(IParent parent, String name, String path,
- String encoding, String key);
+ IErlModule getModuleFromFile(IParent parent, String name,
+ String initialText, String path, String key);
IErlModule getModuleFromText(IParent parent, String name,
String initialText, String key);
@@ -168,4 +168,10 @@ IErlModule getModuleFromText(IParent parent, String name,
ErlangToolkit getToolkit();
Object getModelLock();
+
+ IErlExternalRoot getExternal(final String key);
+
+ void addExternal(final String key, IErlExternalRoot external);
+
+ void removeExternal(final String key);
}
@@ -39,7 +39,7 @@ public Kind getKind() {
}
@Override
- protected boolean buildStructure(final IProgressMonitor pm)
+ public boolean buildStructure(final IProgressMonitor pm)
throws ErlModelException {
if (prebuilt) {
// already done
@@ -16,6 +16,7 @@
import org.erlide.model.internal.root.Openable;
import org.erlide.model.root.ErlModelManager;
import org.erlide.model.root.IErlExternal;
+import org.erlide.model.root.IErlExternalRoot;
import org.erlide.model.root.IErlModel;
import org.erlide.model.root.IErlProject;
import org.erlide.model.services.search.ErlideOpen;
@@ -29,18 +30,15 @@
import com.google.common.collect.Maps;
public class ErlExternalReferenceEntryList extends Openable implements
- IErlExternal {
+ IErlExternalRoot {
private final String externalIncludes, externalModules;
- private final String externalName;
private final List<String> projectIncludes;
public ErlExternalReferenceEntryList(final IParent parent,
- final String name, final String externalName,
- final String externalIncludes, final List<String> projectIncludes,
- final String externalModules) {
+ final String name, final String externalIncludes,
+ final List<String> projectIncludes, final String externalModules) {
super(parent, name);
- this.externalName = externalName;
this.externalIncludes = externalIncludes;
this.projectIncludes = projectIncludes;
this.externalModules = externalModules;
@@ -52,7 +50,7 @@ public Kind getKind() {
}
@Override
- protected boolean buildStructure(final IProgressMonitor pm)
+ public boolean buildStructure(final IProgressMonitor pm)
throws ErlModelException {
// TODO some code duplication within this function
// ErlLogger.debug("ErlExternalReferenceEntryList.buildStructure %s",
@@ -182,10 +180,6 @@ public String getLabelString() {
return getName();
}
- public String getExternalName() {
- return externalName;
- }
-
public boolean hasModuleWithPath(final String path) {
return false;
}
@@ -209,4 +203,22 @@ public boolean hasIncludes() {
return true;
}
+ @Override
+ public void dispose() {
+ removeExternal();
+ super.dispose();
+ }
+
+ @Override
+ public void close() throws ErlModelException {
+ removeExternal();
+ super.close();
+ }
+
+ protected void removeExternal() {
+ ErlModelManager.getErlangModel().removeExternal(
+ externalIncludes + "|" + externalModules + "|"
+ + projectIncludes);
+ }
+
}
@@ -0,0 +1,53 @@
+package org.erlide.model.internal.erlang;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.erlide.model.ErlModelException;
+import org.erlide.model.IParent;
+import org.erlide.model.internal.root.Openable;
+import org.erlide.model.root.IErlElement;
+import org.erlide.model.root.IErlExternalRoot;
+
+public class ErlExternalReferenceEntryListProxy extends Openable implements
+ IErlExternalRoot {
+
+ private final IErlExternalRoot original;
+
+ public ErlExternalReferenceEntryListProxy(final IParent parent,
+ final String name, final IErlExternalRoot original) {
+ super(parent, name);
+ this.original = original;
+ }
+
+ @Override
+ public String getLabelString() {
+ return original.getLabelString();
+ }
+
+ @Override
+ public Kind getKind() {
+ return original.getKind();
+ }
+
+ @Override
+ public boolean isOTP() {
+ return original.isOTP();
+ }
+
+ @Override
+ public boolean hasIncludes() {
+ return original.hasIncludes();
+ }
+
+ @Override
+ public List<IErlElement> internalGetChildren() {
+ return original.internalGetChildren();
+ }
+
+ @Override
+ public boolean buildStructure(final IProgressMonitor pm)
+ throws ErlModelException {
+ return ((Openable) original).buildStructure(pm);
+ }
+}
@@ -158,7 +158,7 @@ private String getInitialText() {
}
@Override
- protected synchronized boolean buildStructure(final IProgressMonitor pm)
+ public synchronized boolean buildStructure(final IProgressMonitor pm)
throws ErlModelException {
if (internalBuildStructure(pm)) {
final IErlModel model = ErlModelManager.getErlangModel();
@@ -10,15 +10,17 @@
import org.erlide.model.IParent;
import org.erlide.model.ModelPlugin;
import org.erlide.model.internal.root.Openable;
+import org.erlide.model.root.IErlElement;
import org.erlide.model.root.IErlExternal;
+import org.erlide.model.root.IErlExternalRoot;
import org.erlide.model.root.IErlProject;
import org.erlide.model.root.OldErlangProjectProperties;
import org.erlide.model.services.search.ErlideOpen;
import org.erlide.model.util.ModelUtils;
import org.erlide.runtime.IRpcSite;
public class ErlOtpExternalReferenceEntryList extends Openable implements
- IErlExternal {
+ IErlExternalRoot {
public ErlOtpExternalReferenceEntryList(final IParent parent,
final String name) {
@@ -31,7 +33,7 @@ public Kind getKind() {
}
@Override
- protected boolean buildStructure(final IProgressMonitor pm)
+ public boolean buildStructure(final IProgressMonitor pm)
throws ErlModelException {
final IErlProject erlProject = ModelUtils.getProject(this);
final OldErlangProjectProperties properties = new OldErlangProjectProperties(
@@ -122,4 +124,9 @@ public IResource getResource() {
public boolean hasIncludes() {
return true;
}
+
+ @Override
+ public List<IErlElement> internalGetChildren() {
+ return super.internalGetChildren();
+ }
}
@@ -397,7 +397,7 @@ public Object clone() {
}
}
- protected List<IErlElement> internalGetChildren() {
+ public List<IErlElement> internalGetChildren() {
return fChildren;
}
@@ -39,7 +39,7 @@ protected ErlFolder(final IFolder folder, final IParent parent) {
}
@Override
- protected boolean buildStructure(final IProgressMonitor pm)
+ public boolean buildStructure(final IProgressMonitor pm)
throws ErlModelException {
final IErlModel model = ErlModelManager.getErlangModel();
final IContainer c = (IContainer) getResource();
@@ -53,6 +53,7 @@
import org.erlide.model.root.IErlElement;
import org.erlide.model.root.IErlElementDelta;
import org.erlide.model.root.IErlElementLocator;
+import org.erlide.model.root.IErlExternalRoot;
import org.erlide.model.root.IErlFolder;
import org.erlide.model.root.IErlModel;
import org.erlide.model.root.IErlModelChangeListener;
@@ -1165,4 +1166,31 @@ public Object getModelLock() {
public ErlangToolkit getToolkit() {
return toolkit;
}
+
+ private final Map<String, IErlExternalRoot> externals = Maps.newHashMap();
+ private final Map<String, Integer> externalRefCounts = Maps.newHashMap();
+
+ @Override
+ public IErlExternalRoot getExternal(final String key) {
+ return externals.get(key);
+ }
+
+ @Override
+ public void removeExternal(final String key) {
+ final Integer integer = externalRefCounts.get(key);
+ if (integer == null || integer.intValue() == 0) {
+ externals.remove(key).dispose();
+ }
+ }
+
+ @Override
+ public void addExternal(final String key, final IErlExternalRoot external) {
+ if (externals.containsKey(key)) {
+ externalRefCounts.put(key, externalRefCounts.get(key) + 1);
+ } else {
+ externals.put(key, external);
+ externalRefCounts.put(key, 1);
+ }
+ }
+
}
@@ -45,13 +45,15 @@
import org.erlide.model.erlang.IErlModule;
import org.erlide.model.erlang.ModuleKind;
import org.erlide.model.internal.erlang.ErlExternalReferenceEntryList;
+import org.erlide.model.internal.erlang.ErlExternalReferenceEntryListProxy;
import org.erlide.model.internal.erlang.ErlOtpExternalReferenceEntryList;
import org.erlide.model.internal.root.ErlModel.External;
import org.erlide.model.root.ErlModelManager;
import org.erlide.model.root.IErlElement;
import org.erlide.model.root.IErlElementLocator;
import org.erlide.model.root.IErlElementVisitor;
import org.erlide.model.root.IErlExternal;
+import org.erlide.model.root.IErlExternalRoot;
import org.erlide.model.root.IErlFolder;
import org.erlide.model.root.IErlModel;
import org.erlide.model.root.IErlModelMarker;
@@ -118,14 +120,14 @@ public ErlProject(final IProject project, final ErlElement parent) {
* @see Openable
*/
@Override
- protected boolean buildStructure(final IProgressMonitor pm)
+ public boolean buildStructure(final IProgressMonitor pm)
throws ErlModelException {
final IResource r = getCorrespondingResource();
// check whether the Erlang project can be opened
if (r == null || !r.isAccessible() || !(r instanceof IContainer)) {
ErlLogger.warn(
- "Project %s has no resources: res:%s acc:%s cont:%s", r,
- (r != null) ? r.isAccessible() : "?",
+ "Project %s has no resources: res:%s acc:%s cont:%s",
+ getName(), r, r != null ? r.isAccessible() : "?",
r instanceof IContainer);
throw new ErlModelException(new ErlModelStatus(
ErlModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this));
@@ -170,7 +172,14 @@ protected boolean buildStructure(final IProgressMonitor pm)
private void addOtpExternals(final List<IErlElement> children) {
final String name = "OTP "
+ getProperties().getRuntimeVersion().toString();
- children.add(new ErlOtpExternalReferenceEntryList(this, name));
+ final IErlModel model = ErlModelManager.getErlangModel();
+ IErlExternalRoot external = model.getExternal(name);
+ if (external == null) {
+ external = new ErlOtpExternalReferenceEntryList(this, name);
+ }
+ model.addExternal(name, external);
+ children.add(new ErlExternalReferenceEntryListProxy(this, name,
+ external));
}
private void addExternals(final List<IErlElement> children) {
@@ -194,9 +203,17 @@ private void addExternals(final List<IErlElement> children) {
}
if (externalIncludes.length() != 0 || externalModules.length() != 0
|| !projectIncludes.isEmpty()) {
- children.add(new ErlExternalReferenceEntryList(this, "Externals",
- "externals", externalIncludes, projectIncludes,
- externalModules));
+ final String key = externalIncludes + "|" + externalModules + "|"
+ + projectIncludes;
+ final IErlModel model = ErlModelManager.getErlangModel();
+ IErlExternalRoot external = model.getExternal(key);
+ if (external == null) {
+ external = new ErlExternalReferenceEntryList(this, "Externals",
+ externalIncludes, projectIncludes, externalModules);
+ }
+ model.addExternal(key, external);
+ children.add(new ErlExternalReferenceEntryListProxy(this,
+ "Externals", external));
}
}
@@ -944,4 +961,10 @@ public boolean visit(final IErlElement element)
public IProject getWorkspaceProject() {
return fProject;
}
+
+ @Override
+ public void close() throws ErlModelException {
+ clearCaches();
+ super.close();
+ }
}
@@ -68,7 +68,7 @@ protected Openable(final IParent parent, final String name) {
*
* @param dirtyRegion
*/
- protected abstract boolean buildStructure(IProgressMonitor pm)
+ public abstract boolean buildStructure(IProgressMonitor pm)
throws ErlModelException;
/*
@@ -317,7 +317,13 @@ public void save(final IProgressMonitor pm, final boolean force)
@Override
public void close() throws ErlModelException {
- // /ErlModelManager.getErlangModelManager().removeInfoAndChildren(this);
+ for (final IErlElement child : getChildren()) {
+ if (child instanceof IOpenable) {
+ final IOpenable openable = (IOpenable) child;
+ if (openable.isOpen()) {
+ openable.close();
+ }
+ }
+ }
}
-
}

0 comments on commit 1765488

Please sign in to comment.