001: /*******************************************************************************
002: * Copyright (c) 2005, 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.product;
011:
012: import java.io.ByteArrayInputStream;
013: import java.io.File;
014: import java.io.FileInputStream;
015: import java.io.IOException;
016: import java.io.InputStream;
017: import java.io.InputStreamReader;
018: import java.lang.reflect.InvocationTargetException;
019: import java.net.MalformedURLException;
020: import java.net.URL;
021:
022: import org.eclipse.core.resources.IContainer;
023: import org.eclipse.core.resources.IFile;
024: import org.eclipse.core.resources.IFolder;
025: import org.eclipse.core.resources.IProject;
026: import org.eclipse.core.runtime.CoreException;
027: import org.eclipse.core.runtime.FileLocator;
028: import org.eclipse.core.runtime.IProgressMonitor;
029: import org.eclipse.core.runtime.IStatus;
030: import org.eclipse.core.runtime.Path;
031: import org.eclipse.core.runtime.Status;
032: import org.eclipse.osgi.util.NLS;
033: import org.eclipse.pde.core.IBaseModel;
034: import org.eclipse.pde.core.plugin.IExtensionsModelFactory;
035: import org.eclipse.pde.core.plugin.IPluginBase;
036: import org.eclipse.pde.core.plugin.IPluginElement;
037: import org.eclipse.pde.core.plugin.IPluginExtension;
038: import org.eclipse.pde.core.plugin.IPluginModelBase;
039: import org.eclipse.pde.core.plugin.PluginRegistry;
040: import org.eclipse.pde.internal.core.TargetPlatformHelper;
041: import org.eclipse.pde.internal.core.iproduct.IProduct;
042: import org.eclipse.pde.internal.core.plugin.WorkspacePluginModelBase;
043: import org.eclipse.pde.internal.ui.PDEPlugin;
044: import org.eclipse.pde.internal.ui.PDEUIMessages;
045: import org.eclipse.pde.internal.ui.util.ModelModification;
046: import org.eclipse.pde.internal.ui.util.PDEModelUtility;
047: import org.eclipse.pde.internal.ui.wizards.templates.ControlStack;
048: import org.eclipse.pde.ui.templates.IVariableProvider;
049: import org.eclipse.swt.widgets.Shell;
050:
051: public class ProductIntroOperation extends BaseManifestOperation
052: implements IVariableProvider {
053:
054: protected String fIntroId;
055: private Shell fShell;
056: private IProduct fProduct;
057: private IProject fProject;
058: private static final String INTRO_POINT = "org.eclipse.ui.intro"; //$NON-NLS-1$
059: private static final String INTRO_CONFIG_POINT = "org.eclipse.ui.intro.config"; //$NON-NLS-1$
060: private static final String INTRO_CLASS = "org.eclipse.ui.intro.config.CustomizableIntroPart"; //$NON-NLS-1$
061: private static final String KEY_PRODUCT_NAME = "productName"; //$NON-NLS-1$
062:
063: public ProductIntroOperation(IProduct product, String pluginId,
064: String introId, Shell shell) {
065: super (shell, pluginId);
066: fIntroId = introId;
067: fProduct = product;
068: fProject = PluginRegistry.findModel(pluginId)
069: .getUnderlyingResource().getProject();
070: }
071:
072: public void run(IProgressMonitor monitor)
073: throws InvocationTargetException, InterruptedException {
074: try {
075: IFile file = getFile();
076: if (!file.exists()) {
077: createNewFile(file);
078: } else {
079: modifyExistingFile(file, monitor);
080: }
081: updateSingleton(monitor);
082: generateFiles(monitor);
083: } catch (CoreException e) {
084: throw new InvocationTargetException(e);
085: }
086: }
087:
088: private void createNewFile(IFile file) throws CoreException {
089: WorkspacePluginModelBase model = (WorkspacePluginModelBase) getModel(file);
090: IPluginBase base = model.getPluginBase();
091: base
092: .setSchemaVersion(TargetPlatformHelper
093: .getTargetVersion() < 3.2 ? "3.0" : "3.2"); //$NON-NLS-1$ //$NON-NLS-2$
094: base.add(createIntroExtension(model));
095: base.add(createIntroConfigExtension(model));
096: model.save();
097: }
098:
099: private IPluginExtension createIntroExtension(IPluginModelBase model)
100: throws CoreException {
101: IPluginExtension extension = model.getFactory()
102: .createExtension();
103: extension.setPoint(INTRO_POINT);
104: extension.add(createIntroExtensionContent(extension));
105: extension.add(createIntroBindingExtensionContent(extension));
106: return extension;
107: }
108:
109: private IPluginExtension createIntroConfigExtension(
110: IPluginModelBase model) throws CoreException {
111: IPluginExtension extension = model.getFactory()
112: .createExtension();
113: extension.setPoint(INTRO_CONFIG_POINT);
114: extension.add(createIntroConfigExtensionContent(extension));
115: return extension;
116: }
117:
118: private IPluginElement createIntroExtensionContent(
119: IPluginExtension extension) throws CoreException {
120: IPluginElement element = extension.getModel().getFactory()
121: .createElement(extension);
122: element.setName("intro"); //$NON-NLS-1$
123: element.setAttribute("id", fIntroId); //$NON-NLS-1$
124: element.setAttribute("class", INTRO_CLASS); //$NON-NLS-1$
125: return element;
126: }
127:
128: private IPluginElement createIntroBindingExtensionContent(
129: IPluginExtension extension) throws CoreException {
130: IPluginElement element = extension.getModel().getFactory()
131: .createElement(extension);
132: element.setName("introProductBinding"); //$NON-NLS-1$
133: element.setAttribute("productId", fProduct.getId()); //$NON-NLS-1$
134: element.setAttribute("introId", fIntroId); //$NON-NLS-1$
135: return element;
136: }
137:
138: private IPluginElement createIntroConfigExtensionContent(
139: IPluginExtension extension) throws CoreException {
140: IPluginElement element = extension.getModel().getFactory()
141: .createElement(extension);
142: element.setName("config"); //$NON-NLS-1$
143: element.setAttribute("id", fPluginId + ".introConfigId"); //$NON-NLS-1$ //$NON-NLS-2$
144: element.setAttribute("introId", fIntroId); //$NON-NLS-1$
145: element.setAttribute("content", "introContent.xml"); //$NON-NLS-1$ //$NON-NLS-2$
146: element.add(createPresentationElement(element));
147:
148: return element;
149: }
150:
151: private IPluginElement createPresentationElement(
152: IPluginElement parent) throws CoreException {
153: IPluginElement presentation = null;
154: IPluginElement implementation = null;
155: IExtensionsModelFactory factory = parent.getModel()
156: .getFactory();
157:
158: presentation = factory.createElement(parent);
159: presentation.setName("presentation"); //$NON-NLS-1$
160: presentation.setAttribute("home-page-id", "root"); //$NON-NLS-1$ //$NON-NLS-2$
161:
162: implementation = factory.createElement(presentation);
163: implementation.setName("implementation"); //$NON-NLS-1$
164: implementation.setAttribute("kind", "html"); //$NON-NLS-1$ //$NON-NLS-2$
165: implementation.setAttribute("style", "content/shared.css"); //$NON-NLS-1$ //$NON-NLS-2$
166: implementation.setAttribute("os", "win32,linux,macosx"); //$NON-NLS-1$ //$NON-NLS-2$
167:
168: presentation.add(implementation);
169:
170: return presentation;
171: }
172:
173: private void modifyExistingFile(IFile file, IProgressMonitor monitor)
174: throws CoreException {
175: IStatus status = PDEPlugin.getWorkspace().validateEdit(
176: new IFile[] { file }, fShell);
177: if (status.getSeverity() != IStatus.OK)
178: throw new CoreException(
179: new Status(
180: IStatus.ERROR,
181: "org.eclipse.pde.ui", IStatus.ERROR, NLS.bind(PDEUIMessages.ProductDefinitionOperation_readOnly, fPluginId), null)); //$NON-NLS-1$
182:
183: ModelModification mod = new ModelModification(file) {
184: protected void modifyModel(IBaseModel model,
185: IProgressMonitor monitor) throws CoreException {
186: if (!(model instanceof IPluginModelBase))
187: return;
188: IPluginModelBase pluginModel = (IPluginModelBase) model;
189: IPluginExtension extension = getExtension(pluginModel,
190: INTRO_POINT);
191: if (extension == null) {
192: extension = createIntroExtension(pluginModel);
193: pluginModel.getPluginBase().add(extension);
194: } else {
195: extension
196: .add(createIntroExtensionContent(extension));
197: extension
198: .add(createIntroBindingExtensionContent(extension));
199: }
200:
201: extension = getExtension(pluginModel,
202: INTRO_CONFIG_POINT);
203: if (extension == null) {
204: extension = createIntroConfigExtension(pluginModel);
205: pluginModel.getPluginBase().add(extension);
206: } else {
207: extension
208: .add(createIntroConfigExtensionContent(extension));
209: }
210: }
211: };
212: PDEModelUtility.modifyModel(mod, monitor);
213: }
214:
215: private IPluginExtension getExtension(IPluginModelBase model,
216: String tPoint) throws CoreException {
217: IPluginExtension[] extensions = model.getPluginBase()
218: .getExtensions();
219: for (int i = 0; i < extensions.length; i++) {
220: String point = extensions[i].getPoint();
221: if (tPoint.equals(point)) {
222: return extensions[i];
223: }
224: }
225: return null;
226: }
227:
228: protected void generateFiles(IProgressMonitor monitor)
229: throws CoreException {
230: monitor
231: .setTaskName(PDEUIMessages.AbstractTemplateSection_generating);
232:
233: URL locationUrl = null;
234: try {
235: locationUrl = new URL(PDEPlugin.getDefault()
236: .getInstallURL(), "templates_3.1/intro/"); //$NON-NLS-1$
237: } catch (MalformedURLException e1) {
238: return;
239: }
240: if (locationUrl == null) {
241: return;
242: }
243: try {
244: locationUrl = FileLocator.resolve(locationUrl);
245: locationUrl = FileLocator.toFileURL(locationUrl);
246: } catch (IOException e) {
247: return;
248: }
249: if ("file".equals(locationUrl.getProtocol())) { //$NON-NLS-1$
250: File templateDirectory = new File(locationUrl.getFile());
251: if (!templateDirectory.exists())
252: return;
253: generateFiles(templateDirectory, fProject, true, false,
254: monitor);
255: }
256: monitor.subTask(""); //$NON-NLS-1$
257: monitor.worked(1);
258: }
259:
260: private void generateFiles(File src, IContainer dst,
261: boolean firstLevel, boolean binary, IProgressMonitor monitor)
262: throws CoreException {
263: File[] members = src.listFiles();
264:
265: for (int i = 0; i < members.length; i++) {
266: File member = members[i];
267: if (member.getName().equals("ext.xml") || //$NON-NLS-1$
268: member.getName().equals("java") || //$NON-NLS-1$
269: member.getName().equals("concept3.xhtml") || //$NON-NLS-1$
270: member.getName().equals("extContent.xhtml")) //$NON-NLS-1$
271: continue;
272: else if (member.isDirectory()) {
273: IContainer dstContainer = null;
274: if (firstLevel) {
275: binary = false;
276: if (member.getName().equals("bin")) { //$NON-NLS-1$
277: binary = true;
278: dstContainer = dst;
279: }
280: }
281: if (dstContainer == null) {
282: dstContainer = dst.getFolder(new Path(member
283: .getName()));
284: }
285: if (dstContainer instanceof IFolder
286: && !dstContainer.exists())
287: ((IFolder) dstContainer)
288: .create(true, true, monitor);
289: generateFiles(member, dstContainer, false, binary,
290: monitor);
291: } else {
292: if (firstLevel)
293: binary = false;
294: InputStream in = null;
295: try {
296: in = new FileInputStream(member);
297: copyFile(member.getName(), in, dst, binary, monitor);
298: } catch (IOException ioe) {
299: } finally {
300: if (in != null)
301: try {
302: in.close();
303: } catch (IOException ioe2) {
304: }
305: }
306: }
307: }
308: }
309:
310: private void copyFile(String fileName, InputStream input,
311: IContainer dst, boolean binary, IProgressMonitor monitor)
312: throws CoreException {
313:
314: monitor.subTask(fileName);
315: IFile dstFile = dst.getFile(new Path(fileName));
316:
317: try {
318: InputStream stream = getProcessedStream(fileName, input,
319: binary);
320: if (dstFile.exists()) {
321: dstFile.setContents(stream, true, true, monitor);
322: } else {
323: dstFile.create(stream, true, monitor);
324: }
325: stream.close();
326:
327: } catch (IOException e) {
328: }
329: }
330:
331: private InputStream getProcessedStream(String fileName,
332: InputStream stream, boolean binary) throws IOException,
333: CoreException {
334: if (binary)
335: return stream;
336:
337: InputStreamReader reader = new InputStreamReader(stream);
338: int bufsize = 1024;
339: char[] cbuffer = new char[bufsize];
340: int read = 0;
341: StringBuffer keyBuffer = new StringBuffer();
342: StringBuffer outBuffer = new StringBuffer();
343: ControlStack preStack = new ControlStack();
344: preStack.setValueProvider(this );
345:
346: boolean replacementMode = false;
347: while (read != -1) {
348: read = reader.read(cbuffer);
349: for (int i = 0; i < read; i++) {
350: char c = cbuffer[i];
351:
352: if (preStack.getCurrentState() == false) {
353: continue;
354: }
355:
356: if (c == '$') {
357: if (replacementMode) {
358: replacementMode = false;
359: String key = keyBuffer.toString();
360: String value = key.length() == 0 ? "$" //$NON-NLS-1$
361: : getReplacementString(fileName, key);
362: outBuffer.append(value);
363: keyBuffer.delete(0, keyBuffer.length());
364: } else {
365: replacementMode = true;
366: }
367: } else {
368: if (replacementMode)
369: keyBuffer.append(c);
370: else {
371: outBuffer.append(c);
372: }
373: }
374: }
375: }
376: return new ByteArrayInputStream(outBuffer.toString().getBytes(
377: fProject.getDefaultCharset()));
378: }
379:
380: private String getReplacementString(String fileName, String key) {
381: if (key.equals(KEY_PRODUCT_NAME)) {
382: return fProduct.getName();
383: }
384: return key;
385: }
386:
387: public Object getValue(String variable) {
388: return null;
389: }
390: }
|