@Override public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException { monitor = Policy.monitorFor(monitor); try { String message = NLS.bind(Messages.resources_settingCharset, getFullPath()); monitor.beginTask(message, Policy.totalWork); // need to get the project as a scheduling rule because we might be creating a new folder/file // to // hold the project settings final ISchedulingRule rule = workspace.getRuleFactory().charsetRule(this); try { workspace.prepareOperation(rule, monitor); ResourceInfo info = getResourceInfo(false, false); checkAccessible(getFlags(info)); workspace.beginOperation(true); workspace.getCharsetManager().setCharsetFor(getFullPath(), newCharset); info = getResourceInfo(false, true); info.incrementCharsetGenerationCount(); monitor.worked(Policy.opWork); } catch (OperationCanceledException e) { workspace.getWorkManager().operationCanceled(); throw e; } finally { workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork)); } } finally { monitor.done(); } }
@Override public void setContents(InputStream content, int updateFlags, IProgressMonitor monitor) throws CoreException { monitor = Policy.monitorFor(monitor); try { String message = NLS.bind(Messages.resources_settingContents, getFullPath()); monitor.beginTask(message, Policy.totalWork); if (workspace.shouldValidate) workspace.validateSave(this); final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this); try { workspace.prepareOperation(rule, monitor); ResourceInfo info = getResourceInfo(false, false); checkAccessible(getFlags(info)); workspace.beginOperation(true); IFileInfo fileInfo = getStore().fetchInfo(); internalSetContents( content, fileInfo, updateFlags, false, Policy.subMonitorFor(monitor, Policy.opWork)); } catch (OperationCanceledException e) { workspace.getWorkManager().operationCanceled(); throw e; } finally { workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork)); } } finally { monitor.done(); FileUtil.safeClose(content); } }
@Override protected IStatus run(IProgressMonitor monitor) { MultiStatus result = new MultiStatus( ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_SETTING_CHARSET, Messages.resources_updatingEncoding, null); monitor = Policy.monitorFor(monitor); try { monitor.beginTask(Messages.resources_charsetUpdating, Policy.totalWork); final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(workspace.getRoot()); try { workspace.prepareOperation(rule, monitor); workspace.beginOperation(true); Map.Entry<IProject, Boolean> next; while ((next = getNextChange()) != null) { // just exit if the system is shutting down or has been shut down // it is too late to change the workspace at this point anyway if (systemBundle.getState() != Bundle.ACTIVE) return Status.OK_STATUS; IProject project = next.getKey(); try { if (project.isAccessible()) { boolean shouldDisableCharsetDeltaJob = next.getValue().booleanValue(); // flush preferences for non-derived resources flushPreferences( getPreferences(project, false, false, true), shouldDisableCharsetDeltaJob); // flush preferences for derived resources flushPreferences( getPreferences(project, false, true, true), shouldDisableCharsetDeltaJob); } } catch (BackingStoreException e) { // we got an error saving String detailMessage = Messages.resources_savingEncoding; result.add( new ResourceStatus( IResourceStatus.FAILED_SETTING_CHARSET, project.getFullPath(), detailMessage, e)); } } monitor.worked(Policy.opWork); } catch (OperationCanceledException e) { workspace.getWorkManager().operationCanceled(); throw e; } finally { workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork)); } } catch (CoreException ce) { return ce.getStatus(); } finally { monitor.done(); } return result; }
protected void mergeEncodingPreferences(IProject project) { Preferences projectRegularPrefs = null; Preferences projectDerivedPrefs = getPreferences(project, false, true, true); if (projectDerivedPrefs == null) return; try { boolean prefsChanged = false; String[] affectedResources; affectedResources = projectDerivedPrefs.keys(); for (int i = 0; i < affectedResources.length; i++) { String path = affectedResources[i]; String value = projectDerivedPrefs.get(path, null); projectDerivedPrefs.remove(path); // lazy creation of non-derived preferences if (projectRegularPrefs == null) projectRegularPrefs = getPreferences(project, true, false, false); projectRegularPrefs.put(path, value); prefsChanged = true; } if (prefsChanged) { Map<IProject, Boolean> projectsToSave = new HashMap<>(); // this is internal change so do not notify charset delta job projectsToSave.put(project, Boolean.TRUE); job.addChanges(projectsToSave); } } catch (BackingStoreException e) { // problems with the project scope... we will miss the changes (but will log) String message = Messages.resources_readingEncoding; Policy.log( new ResourceStatus( IResourceStatus.FAILED_GETTING_CHARSET, project.getFullPath(), message, e)); } }
private boolean isDerivedEncodingStoredSeparately(IProject project) { // be careful looking up for our node so not to create any nodes as side effect Preferences node = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE); try { // TODO once bug 90500 is fixed, should be as simple as this: // String path = project.getName() + IPath.SEPARATOR + ResourcesPlugin.PI_RESOURCES; // return node.nodeExists(path) ? // node.node(path).getBoolean(ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS, false) : false; // for now, take the long way if (!node.nodeExists(project.getName())) return ResourcesPlugin.DEFAULT_PREF_SEPARATE_DERIVED_ENCODINGS; node = node.node(project.getName()); if (!node.nodeExists(ResourcesPlugin.PI_RESOURCES)) return ResourcesPlugin.DEFAULT_PREF_SEPARATE_DERIVED_ENCODINGS; node = node.node(ResourcesPlugin.PI_RESOURCES); return node.getBoolean( ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS, ResourcesPlugin.DEFAULT_PREF_SEPARATE_DERIVED_ENCODINGS); } catch (BackingStoreException e) { // nodeExists failed String message = Messages.resources_readingEncoding; Policy.log( new ResourceStatus( IResourceStatus.FAILED_GETTING_CHARSET, project.getFullPath(), message, e)); return ResourcesPlugin.DEFAULT_PREF_SEPARATE_DERIVED_ENCODINGS; } }
protected void lazyInitialize() { if (descriptors != null) return; IExtensionPoint point = Platform.getExtensionRegistry() .getExtensionPoint(ResourcesPlugin.PI_RESOURCES, ResourcesPlugin.PT_MODEL_PROVIDERS); IExtension[] extensions = point.getExtensions(); descriptors = new HashMap(extensions.length * 2 + 1); for (int i = 0, imax = extensions.length; i < imax; i++) { IModelProviderDescriptor desc = null; try { desc = new ModelProviderDescriptor(extensions[i]); } catch (CoreException e) { Policy.log(e); } if (desc != null) descriptors.put(desc.getId(), desc); } // do cycle detection now so it only has to be done once // cycle detection on a graph subset is a pain detectCycles(); }
Preferences getPreferences( IProject project, boolean create, boolean isDerived, boolean isDerivedEncodingStoredSeparately) { boolean localIsDerived = isDerivedEncodingStoredSeparately ? isDerived : false; String qualifier = localIsDerived ? ProjectPreferences.PREFS_DERIVED_QUALIFIER : ProjectPreferences.PREFS_REGULAR_QUALIFIER; if (create) // create all nodes down to the one we are interested in return new ProjectScope(project).getNode(qualifier).node(ResourcesPlugin.PREF_ENCODING); // be careful looking up for our node so not to create any nodes as side effect Preferences node = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE); try { // TODO once bug 90500 is fixed, should be as simple as this: // String path = project.getName() + IPath.SEPARATOR + ResourcesPlugin.PI_RESOURCES + // IPath.SEPARATOR + ENCODING_PREF_NODE; // return node.nodeExists(path) ? node.node(path) : null; // for now, take the long way if (!node.nodeExists(project.getName())) return null; node = node.node(project.getName()); if (!node.nodeExists(qualifier)) return null; node = node.node(qualifier); if (!node.nodeExists(ResourcesPlugin.PREF_ENCODING)) return null; return node.node(ResourcesPlugin.PREF_ENCODING); } catch (BackingStoreException e) { // nodeExists failed String message = Messages.resources_readingEncoding; Policy.log( new ResourceStatus( IResourceStatus.FAILED_GETTING_CHARSET, project.getFullPath(), message, e)); } return null; }
private void processEntryChanges( IResourceDelta projectDelta, Map<IProject, Boolean> projectsToSave) { // check each resource with user-set encoding to see if it has // been moved/deleted or if derived state has been changed IProject currentProject = (IProject) projectDelta.getResource(); Preferences projectRegularPrefs = getPreferences(currentProject, false, false, true); Preferences projectDerivedPrefs = getPreferences(currentProject, false, true, true); Map<Boolean, String[]> affectedResourcesMap = new HashMap<>(); try { // no regular preferences for this project if (projectRegularPrefs == null) affectedResourcesMap.put(Boolean.FALSE, new String[0]); else affectedResourcesMap.put(Boolean.FALSE, projectRegularPrefs.keys()); // no derived preferences for this project if (projectDerivedPrefs == null) affectedResourcesMap.put(Boolean.TRUE, new String[0]); else affectedResourcesMap.put(Boolean.TRUE, projectDerivedPrefs.keys()); } catch (BackingStoreException e) { // problems with the project scope... we will miss the changes (but will log) String message = Messages.resources_readingEncoding; Policy.log( new ResourceStatus( IResourceStatus.FAILED_GETTING_CHARSET, currentProject.getFullPath(), message, e)); return; } for (Iterator<Boolean> it = affectedResourcesMap.keySet().iterator(); it.hasNext(); ) { Boolean isDerived = it.next(); String[] affectedResources = affectedResourcesMap.get(isDerived); Preferences projectPrefs = isDerived.booleanValue() ? projectDerivedPrefs : projectRegularPrefs; for (int i = 0; i < affectedResources.length; i++) { IResourceDelta memberDelta = projectDelta.findMember(new Path(affectedResources[i])); // no changes for the given resource if (memberDelta == null) continue; if (memberDelta.getKind() == IResourceDelta.REMOVED) { boolean shouldDisableCharsetDeltaJobForCurrentProject = false; // remove the setting for the original location - save its value though String currentValue = projectPrefs.get(affectedResources[i], null); projectPrefs.remove(affectedResources[i]); if ((memberDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) { IPath movedToPath = memberDelta.getMovedToPath(); IResource resource = workspace.getRoot().findMember(movedToPath); if (resource != null) { Preferences encodingSettings = getPreferences( resource.getProject(), true, resource.isDerived(IResource.CHECK_ANCESTORS)); if (currentValue == null || currentValue.trim().length() == 0) encodingSettings.remove(getKeyFor(movedToPath)); else encodingSettings.put(getKeyFor(movedToPath), currentValue); IProject targetProject = workspace.getRoot().getProject(movedToPath.segment(0)); if (targetProject.equals(currentProject)) // if the file was moved inside the same project disable charset listener shouldDisableCharsetDeltaJobForCurrentProject = true; else projectsToSave.put(targetProject, Boolean.FALSE); } } projectsToSave.put( currentProject, Boolean.valueOf(shouldDisableCharsetDeltaJobForCurrentProject)); } } if (moveSettingsIfDerivedChanged( projectDelta, currentProject, projectPrefs, affectedResources)) { // if settings were moved between preferences files disable charset listener so we don't // react to changes made by ourselves projectsToSave.put(currentProject, Boolean.TRUE); } } }
@Override public void create(InputStream content, int updateFlags, IProgressMonitor monitor) throws CoreException { final boolean monitorNull = monitor == null; monitor = Policy.monitorFor(monitor); try { String message = monitorNull ? "" : NLS.bind(Messages.resources_creating, getFullPath()); // $NON-NLS-1$ monitor.beginTask(message, Policy.totalWork); checkValidPath(path, FILE, true); final ISchedulingRule rule = workspace.getRuleFactory().createRule(this); try { workspace.prepareOperation(rule, monitor); checkDoesNotExist(); Container parent = (Container) getParent(); ResourceInfo info = parent.getResourceInfo(false, false); parent.checkAccessible(getFlags(info)); checkValidGroupContainer(parent, false, false); workspace.beginOperation(true); IFileStore store = getStore(); IFileInfo localInfo = store.fetchInfo(); if (BitMask.isSet(updateFlags, IResource.FORCE)) { if (!Workspace.caseSensitive) { if (localInfo.exists()) { String name = getLocalManager().getLocalName(store); if (name == null || localInfo.getName().equals(name)) { delete(true, null); } else { // The file system is not case sensitive and there is already a file // under this location. message = NLS.bind( Messages.resources_existsLocalDifferentCase, new Path(store.toString()).removeLastSegments(1).append(name).toOSString()); throw new ResourceException( IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), message, null); } } } } else { if (localInfo.exists()) { // return an appropriate error message for case variant collisions if (!Workspace.caseSensitive) { String name = getLocalManager().getLocalName(store); if (name != null && !localInfo.getName().equals(name)) { message = NLS.bind( Messages.resources_existsLocalDifferentCase, new Path(store.toString()).removeLastSegments(1).append(name).toOSString()); throw new ResourceException( IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), message, null); } } message = NLS.bind(Messages.resources_fileExists, store.toString()); throw new ResourceException( IResourceStatus.FAILED_WRITE_LOCAL, getFullPath(), message, null); } } monitor.worked(Policy.opWork * 40 / 100); info = workspace.createResource(this, updateFlags); boolean local = content != null; if (local) { try { internalSetContents( content, localInfo, updateFlags, false, Policy.subMonitorFor(monitor, Policy.opWork * 60 / 100)); } catch (CoreException e) { // a problem happened creating the file on disk, so delete from the workspace and disk workspace.deleteResource(this); store.delete(EFS.NONE, null); throw e; // rethrow } catch (OperationCanceledException e) { // the operation of setting contents has been canceled, so delete the file from the // workspace and disk workspace.deleteResource(this); store.delete(EFS.NONE, null); throw e; } } internalSetLocal(local, DEPTH_ZERO); if (!local) getResourceInfo(true, true).clearModificationStamp(); } catch (OperationCanceledException e) { workspace.getWorkManager().operationCanceled(); throw e; } finally { workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork)); } } finally { monitor.done(); FileUtil.safeClose(content); } }