001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.corext.util;
011:
012: import java.io.File;
013: import java.net.URI;
014: import java.util.ArrayList;
015: import java.util.HashMap;
016: import java.util.Iterator;
017: import java.util.List;
018: import java.util.Map;
019:
020: import org.eclipse.core.filesystem.EFS;
021:
022: import org.eclipse.core.runtime.CoreException;
023: import org.eclipse.core.runtime.IPath;
024: import org.eclipse.core.runtime.IStatus;
025: import org.eclipse.core.runtime.MultiStatus;
026: import org.eclipse.core.runtime.Status;
027:
028: import org.eclipse.core.resources.IFile;
029: import org.eclipse.core.resources.IResource;
030: import org.eclipse.core.resources.IResourceStatus;
031: import org.eclipse.core.resources.ResourceAttributes;
032: import org.eclipse.core.resources.ResourcesPlugin;
033:
034: import org.eclipse.jdt.internal.corext.CorextMessages;
035:
036: import org.eclipse.jdt.internal.ui.IJavaStatusConstants;
037: import org.eclipse.jdt.internal.ui.JavaPlugin;
038: import org.eclipse.jdt.internal.ui.JavaUIStatus;
039:
040: public class Resources {
041:
042: private Resources() {
043: }
044:
045: /**
046: * Checks if the given resource is in sync with the underlying file system.
047: *
048: * @param resource the resource to be checked
049: * @return IStatus status describing the check's result. If <code>status.
050: * isOK()</code> returns <code>true</code> then the resource is in sync
051: */
052: public static IStatus checkInSync(IResource resource) {
053: return checkInSync(new IResource[] { resource });
054: }
055:
056: /**
057: * Checks if the given resources are in sync with the underlying file
058: * system.
059: *
060: * @param resources the resources to be checked
061: * @return IStatus status describing the check's result. If <code>status.
062: * isOK() </code> returns <code>true</code> then the resources are in sync
063: */
064: public static IStatus checkInSync(IResource[] resources) {
065: IStatus result = null;
066: for (int i = 0; i < resources.length; i++) {
067: IResource resource = resources[i];
068: if (!resource.isSynchronized(IResource.DEPTH_INFINITE)) {
069: result = addOutOfSync(result, resource);
070: }
071: }
072: if (result != null)
073: return result;
074: return new Status(IStatus.OK, JavaPlugin.getPluginId(),
075: IStatus.OK, "", null); //$NON-NLS-1$
076: }
077:
078: /**
079: * Makes the given resource committable. Committable means that it is
080: * writeable and that its content hasn't changed by calling
081: * <code>validateEdit</code> for the given resource on <tt>IWorkspace</tt>.
082: *
083: * @param resource the resource to be checked
084: * @param context the context passed to <code>validateEdit</code>
085: * @return status describing the method's result. If <code>status.isOK()</code> returns <code>true</code> then the resources are committable.
086: *
087: * @see org.eclipse.core.resources.IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object)
088: */
089: public static IStatus makeCommittable(IResource resource,
090: Object context) {
091: return makeCommittable(new IResource[] { resource }, context);
092: }
093:
094: /**
095: * Makes the given resources committable. Committable means that all
096: * resources are writeable and that the content of the resources hasn't
097: * changed by calling <code>validateEdit</code> for a given file on
098: * <tt>IWorkspace</tt>.
099: *
100: * @param resources the resources to be checked
101: * @param context the context passed to <code>validateEdit</code>
102: * @return IStatus status describing the method's result. If <code>status.
103: * isOK()</code> returns <code>true</code> then the add resources are
104: * committable
105: *
106: * @see org.eclipse.core.resources.IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object)
107: */
108: public static IStatus makeCommittable(IResource[] resources,
109: Object context) {
110: List readOnlyFiles = new ArrayList();
111: for (int i = 0; i < resources.length; i++) {
112: IResource resource = resources[i];
113: if (resource.getType() == IResource.FILE
114: && isReadOnly(resource))
115: readOnlyFiles.add(resource);
116: }
117: if (readOnlyFiles.size() == 0)
118: return new Status(IStatus.OK, JavaPlugin.getPluginId(),
119: IStatus.OK, "", null); //$NON-NLS-1$
120:
121: Map oldTimeStamps = createModificationStampMap(readOnlyFiles);
122: IStatus status = ResourcesPlugin.getWorkspace().validateEdit(
123: (IFile[]) readOnlyFiles.toArray(new IFile[readOnlyFiles
124: .size()]), context);
125: if (!status.isOK())
126: return status;
127:
128: IStatus modified = null;
129: Map newTimeStamps = createModificationStampMap(readOnlyFiles);
130: for (Iterator iter = oldTimeStamps.keySet().iterator(); iter
131: .hasNext();) {
132: IFile file = (IFile) iter.next();
133: if (!oldTimeStamps.get(file)
134: .equals(newTimeStamps.get(file)))
135: modified = addModified(modified, file);
136: }
137: if (modified != null)
138: return modified;
139: return new Status(IStatus.OK, JavaPlugin.getPluginId(),
140: IStatus.OK, "", null); //$NON-NLS-1$
141: }
142:
143: private static Map createModificationStampMap(List files) {
144: Map map = new HashMap();
145: for (Iterator iter = files.iterator(); iter.hasNext();) {
146: IFile file = (IFile) iter.next();
147: map.put(file, new Long(file.getModificationStamp()));
148: }
149: return map;
150: }
151:
152: private static IStatus addModified(IStatus status, IFile file) {
153: IStatus entry = JavaUIStatus.createError(
154: IJavaStatusConstants.VALIDATE_EDIT_CHANGED_CONTENT,
155: Messages.format(CorextMessages.Resources_fileModified,
156: file.getFullPath().toString()), null);
157: if (status == null) {
158: return entry;
159: } else if (status.isMultiStatus()) {
160: ((MultiStatus) status).add(entry);
161: return status;
162: } else {
163: MultiStatus result = new MultiStatus(JavaPlugin
164: .getPluginId(),
165: IJavaStatusConstants.VALIDATE_EDIT_CHANGED_CONTENT,
166: CorextMessages.Resources_modifiedResources, null);
167: result.add(status);
168: result.add(entry);
169: return result;
170: }
171: }
172:
173: private static IStatus addOutOfSync(IStatus status,
174: IResource resource) {
175: IStatus entry = new Status(IStatus.ERROR,
176: ResourcesPlugin.PI_RESOURCES,
177: IResourceStatus.OUT_OF_SYNC_LOCAL, Messages.format(
178: CorextMessages.Resources_outOfSync, resource
179: .getFullPath().toString()), null);
180: if (status == null) {
181: return entry;
182: } else if (status.isMultiStatus()) {
183: ((MultiStatus) status).add(entry);
184: return status;
185: } else {
186: MultiStatus result = new MultiStatus(
187: ResourcesPlugin.PI_RESOURCES,
188: IResourceStatus.OUT_OF_SYNC_LOCAL,
189: CorextMessages.Resources_outOfSyncResources, null);
190: result.add(status);
191: result.add(entry);
192: return result;
193: }
194: }
195:
196: /**
197: * This method is used to generate a list of local locations to
198: * be used in DnD for file transfers.
199: *
200: * @param resources the array of resources to get the local
201: * locations for
202: * @return the local locations
203: */
204: public static String[] getLocationOSStrings(IResource[] resources) {
205: List result = new ArrayList(resources.length);
206: for (int i = 0; i < resources.length; i++) {
207: IPath location = resources[i].getLocation();
208: if (location != null)
209: result.add(location.toOSString());
210: }
211: return (String[]) result.toArray(new String[result.size()]);
212: }
213:
214: /**
215: * Returns the location of the given resource. For local
216: * resources this is the OS path in the local file system. For
217: * remote resource this is the URI.
218: *
219: * @param resource the resource
220: * @return the location string or <code>null</code> if the
221: * location URI of the resource is <code>null</code>
222: */
223: public static String getLocationString(IResource resource) {
224: URI uri = resource.getLocationURI();
225: if (uri == null)
226: return null;
227: return EFS.SCHEME_FILE.equalsIgnoreCase(uri.getScheme()) ? new File(
228: uri).getAbsolutePath()
229: : uri.toString();
230: }
231:
232: public static boolean isReadOnly(IResource resource) {
233: ResourceAttributes resourceAttributes = resource
234: .getResourceAttributes();
235: if (resourceAttributes == null) // not supported on this platform for this resource
236: return false;
237: return resourceAttributes.isReadOnly();
238: }
239:
240: static void setReadOnly(IResource resource, boolean readOnly) {
241: ResourceAttributes resourceAttributes = resource
242: .getResourceAttributes();
243: if (resourceAttributes == null) // not supported on this platform for this resource
244: return;
245:
246: resourceAttributes.setReadOnly(readOnly);
247: try {
248: resource.setResourceAttributes(resourceAttributes);
249: } catch (CoreException e) {
250: JavaPlugin.log(e);
251: }
252: }
253: }
|