001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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.pde.internal.ui.wizards.imports;
011:
012: import java.io.File;
013: import java.lang.reflect.InvocationTargetException;
014: import java.util.List;
015:
016: import org.eclipse.core.resources.IFile;
017: import org.eclipse.core.resources.IFolder;
018: import org.eclipse.core.resources.IProject;
019: import org.eclipse.core.resources.IProjectDescription;
020: import org.eclipse.core.resources.IResource;
021: import org.eclipse.core.resources.IWorkspaceRoot;
022: import org.eclipse.core.resources.IWorkspaceRunnable;
023: import org.eclipse.core.resources.ResourcesPlugin;
024: import org.eclipse.core.runtime.CoreException;
025: import org.eclipse.core.runtime.IPath;
026: import org.eclipse.core.runtime.IProgressMonitor;
027: import org.eclipse.core.runtime.IStatus;
028: import org.eclipse.core.runtime.MultiStatus;
029: import org.eclipse.core.runtime.NullProgressMonitor;
030: import org.eclipse.core.runtime.OperationCanceledException;
031: import org.eclipse.core.runtime.Path;
032: import org.eclipse.core.runtime.Status;
033: import org.eclipse.core.runtime.SubProgressMonitor;
034: import org.eclipse.jdt.core.IClasspathEntry;
035: import org.eclipse.jdt.core.IJavaProject;
036: import org.eclipse.jdt.core.JavaCore;
037: import org.eclipse.jdt.core.JavaModelException;
038: import org.eclipse.osgi.util.NLS;
039: import org.eclipse.pde.core.build.IBuildEntry;
040: import org.eclipse.pde.internal.core.PDECore;
041: import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
042: import org.eclipse.pde.internal.core.ifeature.IFeatureInstallHandler;
043: import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
044: import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin;
045: import org.eclipse.pde.internal.core.natures.PDE;
046: import org.eclipse.pde.internal.ui.PDEPlugin;
047: import org.eclipse.pde.internal.ui.PDEUIMessages;
048: import org.eclipse.team.core.RepositoryProvider;
049: import org.eclipse.team.core.TeamException;
050: import org.eclipse.ui.dialogs.IOverwriteQuery;
051: import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
052: import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
053: import org.eclipse.ui.wizards.datatransfer.ImportOperation;
054:
055: public class FeatureImportOperation implements IWorkspaceRunnable {
056: public interface IReplaceQuery {
057:
058: // return codes
059: public static final int CANCEL = 0;
060: public static final int NO = 1;
061: public static final int YES = 2;
062:
063: /**
064: * Do the callback. Returns YES, NO or CANCEL
065: */
066: int doQuery(IProject project);
067: }
068:
069: private IFeatureModel[] fModels;
070: private boolean fBinary;
071: private IPath fTargetPath;
072:
073: private IWorkspaceRoot fRoot;
074: private IReplaceQuery fReplaceQuery;
075:
076: /**
077: *
078: * @param models
079: * @param targetPath a parent of external project or null
080: * @param replaceQuery
081: */
082: public FeatureImportOperation(IFeatureModel[] models,
083: boolean binary, IPath targetPath, IReplaceQuery replaceQuery) {
084: fModels = models;
085: fBinary = binary;
086: fTargetPath = targetPath;
087: fRoot = ResourcesPlugin.getWorkspace().getRoot();
088: fReplaceQuery = replaceQuery;
089: }
090:
091: /*
092: * @see IWorkspaceRunnable#run(IProgressMonitor)
093: */
094: public void run(IProgressMonitor monitor) throws CoreException,
095: OperationCanceledException {
096: if (monitor == null) {
097: monitor = new NullProgressMonitor();
098: }
099: monitor.beginTask(
100: PDEUIMessages.FeatureImportWizard_operation_creating,
101: fModels.length);
102: try {
103: MultiStatus multiStatus = new MultiStatus(
104: PDEPlugin.getPluginId(),
105: IStatus.OK,
106: PDEUIMessages.FeatureImportWizard_operation_multiProblem,
107: null);
108: for (int i = 0; i < fModels.length; i++) {
109: try {
110: createProject(fModels[i], new SubProgressMonitor(
111: monitor, 1));
112: } catch (CoreException e) {
113: multiStatus.merge(e.getStatus());
114: }
115: if (monitor.isCanceled()) {
116: throw new OperationCanceledException();
117: }
118: }
119: if (!multiStatus.isOK()) {
120: throw new CoreException(multiStatus);
121: }
122: } finally {
123: monitor.done();
124: }
125: }
126:
127: private void createProject(IFeatureModel model,
128: IProgressMonitor monitor) throws CoreException {
129: String name = model.getFeature().getId();
130:
131: IFeaturePlugin[] plugins = model.getFeature().getPlugins();
132: for (int i = 0; i < plugins.length; i++) {
133: if (name.equals(plugins[i].getId())) {
134: name += "-feature"; //$NON-NLS-1$
135: break;
136: }
137:
138: }
139:
140: String task = NLS.bind(
141: PDEUIMessages.FeatureImportWizard_operation_creating2,
142: name);
143: monitor.beginTask(task, 9);
144: try {
145: IProject project = fRoot.getProject(name);
146:
147: if (project.exists()
148: || new File(project.getParent().getLocation()
149: .toFile(), name).exists()) {
150: if (queryReplace(project)) {
151: if (!project.exists())
152: project.create(new SubProgressMonitor(monitor,
153: 1));
154: project.delete(true, true, new SubProgressMonitor(
155: monitor, 1));
156: try {
157: RepositoryProvider.unmap(project);
158: } catch (TeamException e) {
159: }
160: } else {
161: return;
162: }
163: } else {
164: monitor.worked(1);
165: }
166:
167: IProjectDescription description = PDEPlugin.getWorkspace()
168: .newProjectDescription(name);
169: if (fTargetPath != null)
170: description.setLocation(fTargetPath.append(name));
171:
172: project.create(description, new SubProgressMonitor(monitor,
173: 1));
174: if (!project.isOpen()) {
175: project.open(null);
176: }
177: File featureDir = new File(model.getInstallLocation());
178:
179: importContent(featureDir, project.getFullPath(),
180: FileSystemStructureProvider.INSTANCE, null,
181: new SubProgressMonitor(monitor, 1));
182: IFolder folder = project.getFolder("META-INF"); //$NON-NLS-1$
183: if (folder.exists()) {
184: folder.delete(true, null);
185: }
186: if (fBinary) {
187: // Mark this project so that we can show image overlay
188: // using the label decorator
189: project.setPersistentProperty(
190: PDECore.EXTERNAL_PROJECT_PROPERTY,
191: PDECore.BINARY_PROJECT_VALUE);
192: }
193: createBuildProperties(project);
194: setProjectNatures(project, model, monitor);
195: if (project.hasNature(JavaCore.NATURE_ID))
196: setClasspath(project, model, monitor);
197:
198: } finally {
199: monitor.done();
200: }
201: }
202:
203: private void importContent(Object source, IPath destPath,
204: IImportStructureProvider provider, List filesToImport,
205: IProgressMonitor monitor) throws CoreException {
206: IOverwriteQuery query = new IOverwriteQuery() {
207: public String queryOverwrite(String file) {
208: return ALL;
209: }
210: };
211: ImportOperation op = new ImportOperation(destPath, source,
212: provider, query);
213: op.setCreateContainerStructure(false);
214: if (filesToImport != null) {
215: op.setFilesToImport(filesToImport);
216: }
217:
218: try {
219: op.run(monitor);
220: } catch (InvocationTargetException e) {
221: Throwable th = e.getTargetException();
222: if (th instanceof CoreException) {
223: throw (CoreException) th;
224: }
225: IStatus status = new Status(IStatus.ERROR, PDEPlugin
226: .getPluginId(), IStatus.ERROR, e.getMessage(), e);
227: throw new CoreException(status);
228: } catch (InterruptedException e) {
229: throw new OperationCanceledException(e.getMessage());
230: }
231: }
232:
233: private boolean queryReplace(IProject project)
234: throws OperationCanceledException {
235: switch (fReplaceQuery.doQuery(project)) {
236: case IReplaceQuery.CANCEL:
237: throw new OperationCanceledException();
238: case IReplaceQuery.NO:
239: return false;
240: }
241: return true;
242: }
243:
244: private void setProjectNatures(IProject project,
245: IFeatureModel model, IProgressMonitor monitor)
246: throws CoreException {
247: IProjectDescription desc = project.getDescription();
248: if (needsJavaNature(model)) {
249: desc.setNatureIds(new String[] { JavaCore.NATURE_ID,
250: PDE.FEATURE_NATURE });
251: } else {
252: desc.setNatureIds(new String[] { PDE.FEATURE_NATURE });
253: }
254: project
255: .setDescription(desc,
256: new SubProgressMonitor(monitor, 1));
257: }
258:
259: private void setClasspath(IProject project, IFeatureModel model,
260: IProgressMonitor monitor) throws JavaModelException {
261: IJavaProject jProject = JavaCore.create(project);
262:
263: IClasspathEntry jreCPEntry = JavaCore
264: .newContainerEntry(new Path(
265: "org.eclipse.jdt.launching.JRE_CONTAINER")); //$NON-NLS-1$
266:
267: String libName = model.getFeature().getInstallHandler()
268: .getLibrary();
269: IClasspathEntry handlerCPEntry = JavaCore.newLibraryEntry(
270: project.getFullPath().append(libName), null, null);
271:
272: jProject.setRawClasspath(new IClasspathEntry[] { jreCPEntry,
273: handlerCPEntry }, monitor);
274: }
275:
276: private boolean needsJavaNature(IFeatureModel model) {
277: IFeatureInstallHandler handler = model.getFeature()
278: .getInstallHandler();
279: if (handler == null) {
280: return false;
281: }
282: String libName = handler.getLibrary();
283: if (libName == null || libName.length() <= 0) {
284: return false;
285: }
286: File lib = new File(model.getInstallLocation(), libName);
287: return lib.exists();
288: }
289:
290: private void createBuildProperties(IProject project) {
291: IFile file = project.getFile("build.properties"); //$NON-NLS-1$
292: if (!file.exists()) {
293: WorkspaceBuildModel model = new WorkspaceBuildModel(file);
294: IBuildEntry ientry = model.getFactory().createEntry(
295: "bin.includes"); //$NON-NLS-1$
296: try {
297: IResource[] res = project.members();
298: for (int i = 0; i < res.length; i++) {
299: String path = res[i].getProjectRelativePath()
300: .toString();
301: if (!path.equals(".project")) //$NON-NLS-1$
302: ientry.addToken(path);
303: }
304: model.getBuild().add(ientry);
305: model.save();
306: } catch (CoreException e) {
307: }
308: }
309: }
310:
311: }
|