/******************************************************************************* * Copyright © 2008, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.ide.core.internal.generation; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.edt.ide.core.EDTCoreIDEPlugin; import org.eclipse.edt.ide.core.CoreIDEPluginStrings; import org.eclipse.edt.ide.core.Logger; import org.eclipse.edt.ide.core.generation.IGenerationUnit; import org.eclipse.edt.ide.core.internal.utils.ProjectPathUtility; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.wst.sse.core.internal.provisional.IModelManager; import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML; import org.w3c.dom.Element; import org.w3c.dom.Node; public class GenerateCommandFileOperation { /** * Command File extension */ public static final String EGL_COMMAND_FILE_EXTENSION = "xml"; //$NON-NLS-1$ /** * genPartsOperation - this object. */ private static final GenerateCommandFileOperation generateCmdFileOperation = new GenerateCommandFileOperation(); private static ArrayList commandFileRequestList = new ArrayList(); private class CommandFileGenerator { private static final String EGLCOMMANDS_EGLPATH_ATTRIBUTE = "eglpath"; //$NON-NLS-1$ private static final String GENERATE_ELEMENT = "generate"; //$NON-NLS-1$ private static final String GENERATE_FILE_ATTRIBUTE = "file"; //$NON-NLS-1$ private static final String BUILD_DESCRIPTOR_ELEMENT = "buildDescriptor"; //$NON-NLS-1$ private static final String BUILD_DESCRIPTOR_NAME_ATTRIBUTE = "name"; //$NON-NLS-1$ private static final String BUILD_DESCRIPTOR_FILE_ATTRIBUTE = "file"; //$NON-NLS-1$ private IDOMDocument document = null; private IPath path = null; private final String MODEL_ID = EDTCoreIDEPlugin.EGL_UTILITIES + "." + EGL_COMMAND_FILE_EXTENSION; //$NON-NLS-1$ /** * Constructor for EGLCreateCommandFileCommand. */ public CommandFileGenerator(String filePath) { super(); setPath(filePath); initialize(); } /** * Method setPath. * @param filePath */ private void setPath(String filePath) { path = new Path(filePath); if(path.getFileExtension() == null) { path = path.addFileExtension(EGL_COMMAND_FILE_EXTENSION); } else if(!path.getFileExtension().equalsIgnoreCase(EGL_COMMAND_FILE_EXTENSION)) { path = path.addFileExtension(EGL_COMMAND_FILE_EXTENSION); } } /** * Discard this documents model */ public void dispose() { if(document != null) { document.getModel().releaseFromEdit(); } } /** * Set up this command file document */ private void initialize() { IModelManager modelManager = StructuredModelManager.getModelManager(); IDOMModel xmlModel; try { xmlModel = (IDOMModel) modelManager.getModelForEdit( MODEL_ID, new ByteArrayInputStream(CommandFile.createEmptyCommandFile().getBytes()), null); document = xmlModel.getDocument(); } catch (UnsupportedEncodingException e) { Logger.log(this, "EGLCreateCommandFileOperation.EGLCreateCommandFileCommand::initialize() - Unsupported Encoding Exception", e); //$NON-NLS-1$ } catch (IOException e) { Logger.log(this, "EGLCreateCommandFileOperation.EGLCreateCommandFileCommand::initialize() - IOException", e); //$NON-NLS-1$ } } /** * Set the egl path in this document */ private void setEGLPath(String path) { if(document != null) { document.getDocumentElement().setAttribute(EGLCOMMANDS_EGLPATH_ATTRIBUTE, path); } } /** * Create a new generate command */ public void createGenerateCommand(String partFileName, String buildDescriptorFileName, String buildDescriptorName) { if(document != null) { Node genElement = createGenerateElement(document.getDocumentElement(), partFileName); // create child createBuildDescriptorElement(genElement, buildDescriptorFileName, buildDescriptorName); } } /** * Method createBuildDescriptorElement. * @param buildDescriptorFileName * @param buildDescriptorPartName * @return Node */ private Node createBuildDescriptorElement(Node parent, String buildDescriptorFileName, String buildDescriptorName) { Element bdElement = null; if(document != null) { bdElement = document.createElement(BUILD_DESCRIPTOR_ELEMENT); bdElement.setAttribute(BUILD_DESCRIPTOR_NAME_ATTRIBUTE, buildDescriptorName); bdElement.setAttribute(BUILD_DESCRIPTOR_FILE_ATTRIBUTE, buildDescriptorFileName); parent.appendChild(bdElement); } return bdElement; } /** * Create a new generate element */ private Node createGenerateElement(Node parent, String partFileName) { Element genElement = null; if(document != null) { genElement = document.createElement(GENERATE_ELEMENT); genElement.setAttribute(GENERATE_FILE_ATTRIBUTE, partFileName); parent.appendChild(genElement); } return genElement; } /** * Write to disk */ public void write() throws IOException { if(document != null) { // extra safety check so that we don't write a file // that is named a drive letter. (ex: "c:\") if(path.segmentCount() > 0) { // create a directory if we need to if(createDirectoryIfNecessary(path) == true) { // check to see if we can create/ write to the file File file = path.toFile(); if((file.exists() && file.canWrite()) || (!file.exists() && file.createNewFile())) { // format the document formatDocument(); FileOutputStream stream = new FileOutputStream(file); try { // write the document document.getModel().save(stream); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } stream.close(); } else { // error openErrorDialog(); } } else { // report error Logger.log(this, "EGLGenerateCommandFileOperation.EGLCommandFileGenerator::write() - error writing file"); //$NON-NLS-1$ } } else { Logger.log(this, "EGLGenerateCommandFileOperation.EGLCommandFileGenerator::write() - invalid path"); //$NON-NLS-1$ } } } /** * Method openErrorDialog. */ private void openErrorDialog() { Display display = Display.getDefault(); if (display != null) { display.asyncExec(new Runnable() { public void run() { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if(window != null) { MessageDialog.openError(window.getShell(), CoreIDEPluginStrings.GenerateCommandFileOperation_ErrorMessage_Title, CoreIDEPluginStrings.bind(CoreIDEPluginStrings.GenerateCommandFileOperation_ErrorMessage_Message, path.toOSString())); } } }); } } /** * Format this document */ private void formatDocument() { if(document != null) { FormatProcessorXML processor = new FormatProcessorXML(); processor.formatModel(document.getModel()); } } /** * If the directory from this path does not exist, create it */ private boolean createDirectoryIfNecessary(IPath path) { boolean result = true; File file = null; // if we have more than 0 segments, remove the last segment if(path.segmentCount() > 0) { // get everything but the last segment path = path.removeLastSegments(1); } file = new File(path.toOSString()); // if this directory doesn't exist, create it if(!file.exists()) { result = file.mkdir(); } return result; } } /** * GenerationWizardGeneratePartsOperation constructor comment. */ private GenerateCommandFileOperation() { super(); } public static GenerateCommandFileOperation getInstance() { return generateCmdFileOperation; } public void generate(IGenerationUnit[] parts, String cmdFilePath, IProject[] projects, boolean createEGLPath) { GenerateCommandFileRequest request = new GenerateCommandFileRequest(parts, cmdFilePath, projects, createEGLPath); synchronized(commandFileRequestList){ commandFileRequestList.add(request); } // Create a new job for each generation request Job generationJob = createGenerationJob(); generationJob.schedule(); } /** * Insert the method's description here. * Creation date: (12/17/2001 2:12:24 PM) * @return java.util.List */ private void generateCommandFile(org.eclipse.core.runtime.IProgressMonitor monitor) { synchronized(generateCmdFileOperation) { GenerateCommandFileRequest request = null; IGenerationUnit[] partList = null; synchronized(commandFileRequestList) { if(commandFileRequestList.size() > 0) { request = (GenerateCommandFileRequest)commandFileRequestList.remove(0); } } if(request != null) { // create a new createCommand CommandFileGenerator createCommand = new CommandFileGenerator(request.getEglCommandFilePath()); // create the egl path if necessary if(request.isCreateEGLPath()) { // set the EGLPath for this create command createCommand.setEGLPath(ProjectPathUtility.getEglPathString(request.getProjects())); } // get a list of the parts to put in the command file partList = request.getGenerationUnits(); // setup the monitor monitor.beginTask(CoreIDEPluginStrings.GenerateCommandFileOperation_TaskName, (partList.length * 2)); // generate the commands for(int i=0; i<partList.length; i++) { monitor.worked(1); if(monitor.isCanceled()) { break; } PartWrapper part = partList[i].getPart(); IEGLPartWrapper bdWrapper = partList[i].getBuildDescriptor(); Path partPath = new Path(part.getPartPath()); Path bdPath = new Path(bdWrapper.getPartPath()); monitor.subTask(CoreIDEPluginStrings.bind(CoreIDEPluginStrings.GenerateCommandFileOperation_SubTaskName, part.getPartName())); // invoke the command file creation createCommand.createGenerateCommand(partPath.makeRelative().toOSString(), bdPath.makeRelative().toOSString(), bdWrapper.getPartName()); monitor.worked(1); } try { createCommand.write(); } catch (IOException e) { Logger.log(this, "EGLGenerateCommandFileOperation.process(): Error during command file write", e); //$NON-NLS-1$ } createCommand.dispose(); monitor.done(); } } } /** * Create a job to run the part generation. This job will block the entire worskpace for writing */ private Job createGenerationJob() { Job generationJob = new Job(CoreIDEPluginStrings.GenerateCommandFileOperation_JobName) { /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) */ public IStatus run(IProgressMonitor monitor) { WorkspaceModifyOperation modifyOperation = new WorkspaceModifyOperation(){ /* (non-Javadoc) * @see org.eclipse.ui.actions.WorkspaceModifyOperation#execute(org.eclipse.core.runtime.IProgressMonitor) */ protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { generateCommandFile(monitor); }}; try { modifyOperation.run(monitor); } catch (InvocationTargetException e) { Logger.log(this, "EGLGenerateCommandFileOperation.createGenerationJob(): InvocationTargetException", e); //$NON-NLS-1$ } catch (InterruptedException e) { Logger.log(this, "EGLGenerateCommandFileOperation.createGenerationJob(): InterruptedException", e); //$NON-NLS-1$ } return Status.OK_STATUS; } }; generationJob.setRule(ResourcesPlugin.getWorkspace().getRoot()); generationJob.setSystem(false); generationJob.setPriority(Job.LONG); generationJob.setUser(true); return generationJob; } }