1 11 package org.eclipse.core.internal.resources; 12 13 import java.util.*; 14 import org.eclipse.core.internal.utils.Cache; 15 import org.eclipse.core.resources.IProject; 16 import org.eclipse.core.resources.ProjectScope; 17 import org.eclipse.core.runtime.*; 18 import org.eclipse.core.runtime.content.*; 19 import org.eclipse.core.runtime.content.IContentTypeManager.ISelectionPolicy; 20 import org.eclipse.core.runtime.preferences.*; 21 import org.osgi.service.prefs.BackingStoreException; 22 import org.osgi.service.prefs.Preferences; 23 24 31 public class ProjectContentTypes { 32 33 39 private class ProjectContentTypeSelectionPolicy implements ISelectionPolicy, IScopeContext { 40 private Project project; 42 private IScopeContext projectScope; 44 45 public ProjectContentTypeSelectionPolicy(Project project) { 46 this.project = project; 47 this.projectScope = new ProjectScope(project); 48 } 49 50 53 public boolean equals(Object obj) { 54 if (this == obj) 55 return true; 56 if (!(obj instanceof IScopeContext)) 57 return false; 58 IScopeContext other = (IScopeContext) obj; 59 if (!getName().equals(other.getName())) 60 return false; 61 IPath location = getLocation(); 62 return location == null ? other.getLocation() == null : location.equals(other.getLocation()); 63 } 64 65 private IScopeContext getDelegate() { 66 if (!usesContentTypePreferences(project.getName())) 67 return ProjectContentTypes.INSTANCE_SCOPE; 68 return projectScope; 69 } 70 71 public IPath getLocation() { 72 return getDelegate().getLocation(); 73 } 74 75 public String getName() { 76 return getDelegate().getName(); 77 } 78 79 public IEclipsePreferences getNode(String qualifier) { 80 return getDelegate().getNode(qualifier); 81 } 82 83 86 public int hashCode() { 87 return getName().hashCode(); 88 } 89 90 public IContentType[] select(IContentType[] candidates, boolean fileName, boolean content) { 91 return ProjectContentTypes.this.select(project, candidates, fileName, content); 92 } 93 } 94 95 private static final String CONTENT_TYPE_PREF_NODE = "content-types"; 97 static final InstanceScope INSTANCE_SCOPE = new InstanceScope(); 98 99 private static final String PREF_LOCAL_CONTENT_TYPE_SETTINGS = "enabled"; private static final Preferences PROJECT_SCOPE = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE); 101 private Cache contentTypesPerProject; 102 private Workspace workspace; 103 104 static boolean usesContentTypePreferences(String projectName) { 105 try { 106 Preferences node = PROJECT_SCOPE; 108 if (!node.nodeExists(projectName)) 111 return false; 112 node = node.node(projectName); 113 if (!node.nodeExists(Platform.PI_RUNTIME)) 114 return false; 115 node = node.node(Platform.PI_RUNTIME); 116 if (!node.nodeExists(CONTENT_TYPE_PREF_NODE)) 117 return false; 118 node = node.node(CONTENT_TYPE_PREF_NODE); 119 return node.getBoolean(PREF_LOCAL_CONTENT_TYPE_SETTINGS, false); 120 } catch (BackingStoreException e) { 121 } 123 return false; 124 } 125 126 public ProjectContentTypes(Workspace workspace) { 127 this.workspace = workspace; 128 this.contentTypesPerProject = new Cache(5, 30, 0.4); 130 } 131 132 135 private Set collectAssociatedContentTypes(Project project) { 136 String [] enabledNatures = workspace.getNatureManager().getEnabledNatures(project); 137 if (enabledNatures.length == 0) 138 return Collections.EMPTY_SET; 139 Set related = new HashSet(enabledNatures.length); 140 for (int i = 0; i < enabledNatures.length; i++) { 141 ProjectNatureDescriptor descriptor = (ProjectNatureDescriptor) workspace.getNatureDescriptor(enabledNatures[i]); 142 if (descriptor == null) 143 continue; 145 String [] natureContentTypes = descriptor.getContentTypeIds(); 146 for (int j = 0; j < natureContentTypes.length; j++) 147 related.add(natureContentTypes[j]); 149 } 150 return related; 151 } 152 153 public void contentTypePreferencesChanged(IProject project) { 154 final ProjectInfo info = (ProjectInfo) ((Project) project).getResourceInfo(false, false); 155 if (info != null) 156 info.setMatcher(null); 157 } 158 159 162 private IContentTypeMatcher createMatcher(Project project) { 163 ProjectContentTypeSelectionPolicy projectContentTypeSelectionPolicy = new ProjectContentTypeSelectionPolicy(project); 164 return Platform.getContentTypeManager().getMatcher(projectContentTypeSelectionPolicy, projectContentTypeSelectionPolicy); 165 } 166 167 private Set getAssociatedContentTypes(Project project) { 168 final ResourceInfo info = project.getResourceInfo(false, false); 169 if (info == null) 170 return null; 172 final String projectName = project.getName(); 173 synchronized (contentTypesPerProject) { 174 Cache.Entry entry = contentTypesPerProject.getEntry(projectName); 175 if (entry != null) 176 if (entry.getTimestamp() == info.getContentId()) 178 return (Set) entry.getCached(); 180 Set result = collectAssociatedContentTypes(project); 182 if (entry == null) 183 entry = contentTypesPerProject.addEntry(projectName, result, info.getContentId()); 185 else { 186 entry.setTimestamp(info.getContentId()); 188 entry.setCached(result); 189 } 190 return result; 191 } 192 } 193 194 public IContentTypeMatcher getMatcherFor(Project project) throws CoreException { 195 ProjectInfo info = (ProjectInfo) project.getResourceInfo(false, false); 196 if (info == null) 198 project.checkAccessible(project.getFlags(info)); 199 IContentTypeMatcher matcher = info.getMatcher(); 200 if (matcher != null) 201 return matcher; 202 matcher = createMatcher(project); 203 info.setMatcher(matcher); 204 return matcher; 205 } 206 207 218 final IContentType[] select(Project project, IContentType[] candidates, boolean fileName, boolean content) { 219 if (candidates.length < 2) 221 return candidates; 222 final Set associated = getAssociatedContentTypes(project); 223 if (associated == null || associated.isEmpty()) 224 return candidates; 226 int associatedCount = 0; 227 for (int i = 0; i < candidates.length; i++) 228 if (associated.contains(candidates[i].getId())) { 230 if (associatedCount < i) { 232 final IContentType promoted = candidates[i]; 233 for (int j = i; j > associatedCount; j--) 235 candidates[j] = candidates[j - 1]; 236 candidates[associatedCount] = promoted; 238 } 239 associatedCount++; 240 } 241 return candidates; 242 } 243 } | Popular Tags |