diff options
author | Mikhail Sennikovsky | 2007-04-26 17:07:39 +0000 |
---|---|---|
committer | Mikhail Sennikovsky | 2007-04-26 17:07:39 +0000 |
commit | c5603e5a0edba5569a4835e2ffed9d14c1958c9d (patch) | |
tree | 7fe1781e1c8833334c2b73ee9776c22369aeb56a /core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine | |
parent | 6741a8d019b2908ddd9ae80d086448eff4fba303 (diff) | |
download | org.eclipse.cdt-c5603e5a0edba5569a4835e2ffed9d14c1958c9d.tar.gz org.eclipse.cdt-c5603e5a0edba5569a4835e2ffed9d14c1958c9d.tar.xz org.eclipse.cdt-c5603e5a0edba5569a4835e2ffed9d14c1958c9d.zip |
Template Engine submission from Bala Torati (Symbian) with some modifications and bug-fixes (see Bug 160012)
Diffstat (limited to 'core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine')
28 files changed, 4002 insertions, 0 deletions
diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/SharedDefaults.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/SharedDefaults.java new file mode 100644 index 00000000000..7872ba64e37 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/SharedDefaults.java @@ -0,0 +1,325 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine; + +import java.io.File; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Result; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + + +/** + * Processes the shared default values. Updates and Persists new key - value (default) pair + */ + +public class SharedDefaults extends HashMap/*<String, String>*/ { + private static final long serialVersionUID = 0000000000L; + + public Document document; + private File parsedXML; + private File backUpSharedXML; + + /** + * HashMap's for persistence + */ + private HashMap/*<String, String>*/ sharedDefaultsMap; + private HashMap/*<String, String>*/ persistDataMap; + private HashMap/*<String, String>*/ tableDataMap; + + /** + * Two XML files here supports to provide consistent writing of data into + * them even during some destructive events which can happen during data + * persistence + */ + private static final String SHARED_DEFAULTS_DOT_XML = "shareddefaults.xml"; //$NON-NLS-1$ + private static final String SHARED_DEFAULTS_DOT_BACKUP_DOT_XML = "shareddefaults.backup.xml"; //$NON-NLS-1$ + + /** + * Static reference string for getting (GET) and storing (SET) + * shareddefaults.xml + */ + + public static final String SET = "SET"; //$NON-NLS-1$ + public static final String GET = "GET"; //$NON-NLS-1$ + + /** + * Specifies the folder name present in the plugin + */ + public static final String ResourceFolder = "resources"; //$NON-NLS-1$ + + /** + * Static reference of Singleton SharedDefault Instance + */ + private static SharedDefaults SHAREDDEFAULTS = new SharedDefaults(); + + /** + * Returns static SharedDefaults Instance + * + * @return + */ + + public static SharedDefaults getInstance() { + return SHAREDDEFAULTS; + } + + /** + * Default Constructor for creating and instantiating objects. On the + * startup of Template Engine, if it checks for the existence of + * TempSharedDefaultsXML file, then it is determined that the last Template + * Engine process under went some System destructive events and takes up + * reconstructive process to regain the consistent data by persisting all + * information first into temporary file and then into actual file. + */ + + public SharedDefaults() { + sharedDefaultsMap = new HashMap/*<String, String>*/(); + persistDataMap = new HashMap/*<String, String>*/(); + tableDataMap = new HashMap/*<String, String>*/(); + + // The conditional controls here is provided to have consistent + // data storage in the file during System crash or + // Power shutdown during data persistence into the file. + + parsedXML = TemplateEngineHelper.getSharedDefaultLocation(SHARED_DEFAULTS_DOT_XML); + backUpSharedXML = TemplateEngineHelper.getSharedDefaultLocation(SHARED_DEFAULTS_DOT_BACKUP_DOT_XML); + + if (backUpSharedXML.exists()) + swapXML(); + + initSharedDefaults(); + } + + /** + * This method instantiates the SharedDefaults process by gathering XML + * document and creating shared key-value pair in HashMap. Also creates a + * new XML file if none exists and adds the default XML format. + */ + + private void initSharedDefaults() { + String key = null; + String value = null; + + try { + long length = parsedXML.length(); + // Adds defaultXML format if the file length is zero + if (length == 0) { + parsedXML = createDefaultXMLFormat(parsedXML); + } + document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(parsedXML.toURL().openStream()); + } catch (Exception exp) { + TemplateEngineUtil.log(exp); + } + + List/*<Element>*/ sharedElementList = TemplateEngine.getChildrenOfElement(document.getDocumentElement()); + int listSize = sharedElementList.size(); + for (int i = 0; i < listSize; i++) { + Element xmlElement = (Element) sharedElementList.get(i); + key = xmlElement.getAttribute(TemplateEngineHelper.ID); + value = xmlElement.getAttribute(TemplateEngineHelper.VALUE); + if (key != null && !key.trim().equals("")) { + sharedDefaultsMap.put(key, value); + } + } + } + + /** + * This method updates the HashMap with new key-value pair into the XML file + * + * @param sharedMap + */ + + public void updateShareDefaultsMap(Map/*<String, String>*/ sharedMap) { + sharedDefaultsMap.putAll(sharedMap); + persistSharedValueMap(); + } + + /** + * This method persists the latest data (HashMap) in the XML file New data + * obtained from the PreferencePage GUI. + */ + + public void persistSharedValueMap() { + generateSharedXML(backUpSharedXML); + generateSharedXML(parsedXML); + swapXML(); + } + + /** + * This method returns the latest key value pair (HashMap) + * + * @return HashMap + */ + + public Map/*<String, String>*/ getSharedDefaultsMap() { + return sharedDefaultsMap; + } + + /** + * Adds data to the backend XML (persistence) Data obtained from the + * PreferencePage GUI. + */ + + public void addToBackEndStorage(String name, String value) { + if (sharedDefaultsMap != null) { + tableDataMap.putAll(sharedDefaultsMap); + } + + tableDataMap.put(name, value); + updateShareDefaultsMap(tableDataMap); + } + + /** + * Updates backend with changed value for a specific key(name) + * + * @param updateName + * @param updateValue + */ + + public void updateToBackEndStorage(String updateName, String updateValue) { + try { + document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(parsedXML.toURL().openStream()); + } catch (Exception exp) { + TemplateEngineUtil.log(exp); + } + + persistDataMap.putAll(sharedDefaultsMap); + List/*<Element>*/ sharedElementList = TemplateEngine.getChildrenOfElement(document.getDocumentElement()); + int elementListSize = sharedElementList.size(); + + for (int i = 0; i < elementListSize; i++) { + Element xmlElement = (Element) sharedElementList.get(i); + String name = xmlElement.getAttribute(TemplateEngineHelper.ID); + + if (updateName.equals(name)) { + persistDataMap.put(updateName, updateValue); + } + } + + updateShareDefaultsMap(persistDataMap); + } + + /** + * Deletes the key-value pair from the backend with Key as identifier. + * + * @param deleteName + */ + public void deleteBackEndStorage(String[] deleteName) { + + try { + document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(parsedXML.toURL().openStream()); + } catch (Exception exp) { + TemplateEngineUtil.log(exp); + } + + List/*<Element>*/ sharedElementList = TemplateEngine.getChildrenOfElement(document.getDocumentElement()); + int elementListSize = sharedElementList.size(); + for (int i = 0; i < elementListSize; i++) { + + Element xmlElement = (Element) sharedElementList.get(i); + String name = xmlElement.getAttribute(TemplateEngineHelper.ID); + + for (int k = 0; k < deleteName.length; k++) { + if (deleteName[k].equals(name)) { + xmlElement.removeAttribute(name); + sharedDefaultsMap.remove(name); + } + } + } + + updateShareDefaultsMap(sharedDefaultsMap); + } + + /** + * This method returns the default XMLFormat for the newly created XML file + * + * @param parsedXML + * @return + */ + + private File createDefaultXMLFormat(File xmlFile) { + Document d; + try { + d = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + TemplateEngineUtil.log(e); + return xmlFile; + } + Node rootElement = d.appendChild(d.createElement("SharedRoot")); //$NON-NLS-1$ + Element element = (Element) rootElement.appendChild(d.createElement("SharedProperty")); //$NON-NLS-1$ + element.setAttribute(TemplateEngineHelper.ID, ""); //$NON-NLS-1$ + element.setAttribute(TemplateEngineHelper.VALUE, ""); //$NON-NLS-1$ + + DOMSource domSource = new DOMSource(d); + TransformerFactory transFactory = TransformerFactory.newInstance(); + Result fileResult = new StreamResult(xmlFile); + try { + transFactory.newTransformer().transform(domSource, fileResult); + } catch (Throwable t) { + TemplateEngineUtil.log(t); + } + return xmlFile; + } + + /** + * This method generates XML file for backupshareddefaults and + * shareddefaults to support consistent persistency + */ + + private void generateSharedXML(File xmlFile) { + Document d; + try { + d = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + TemplateEngineUtil.log(e); + return; + } + Node rootElement = d.appendChild(d.createElement("SharedRoot")); //$NON-NLS-1$ + + for(Iterator i = sharedDefaultsMap.keySet().iterator(); i.hasNext(); ) { + String key = (String) i.next(); + Element element = (Element) rootElement.appendChild(d.createElement("SharedProperty")); //$NON-NLS-1$ + element.setAttribute(TemplateEngineHelper.ID, key); + element.setAttribute(TemplateEngineHelper.VALUE, (String) sharedDefaultsMap.get(key)); + } + + DOMSource domSource = new DOMSource(d); + TransformerFactory transFactory = TransformerFactory.newInstance(); + Result fileResult = new StreamResult(xmlFile); + try { + transFactory.newTransformer().transform(domSource, fileResult); + } catch (Throwable t) { + TemplateEngineUtil.log(t); + } + } + + /** + * This method swaps the backup file name to XML file containing latest or + * persisted data + */ + + private void swapXML() { + if (parsedXML.exists()) + parsedXML.delete(); + backUpSharedXML.renameTo(parsedXML); + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateCore.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateCore.java new file mode 100644 index 00000000000..5e28f4ddc9b --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateCore.java @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine; + +import java.io.IOException; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.TemplateProcessHandler; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.xml.sax.SAXException; + + +/** + * TemplateCore class is responsible providing the non-UI part of template and + * initiating process part of Template Engine. This is created per TemplateDescriptor basis. + * Once The Template is created it creates a TemplateDescriptor for the XML file name given. + * Template class extends this class with additional UI elements that are part of the template. + * + * @since 4.0 + */ +public class TemplateCore { + + private static final String DESCRIPTION = "description"; //$NON-NLS-1$ + private static final String LABEL = "label"; //$NON-NLS-1$ + private static final String ID = "id"; //$NON-NLS-1$ + + private static Map/*<TemplateInfo, Template>*/ templateCache = new HashMap/*<TemplateInfo, Template>*/(); + + public static final Comparator/*<Template>*/ TEMPLATE_ID_CASE_INSENSITIVE_COMPARATOR = new Comparator/*<Template>*/() { + public int compare(Object/*Template*/ t1, Object/*Template*/ t2) { + return String.CASE_INSENSITIVE_ORDER.compare(((TemplateCore)t1).getTemplateId(), ((TemplateCore)t2).getTemplateId()); + } + }; + + private TemplateDescriptor templateDescriptor; + private Map/*<String, String>*/ valueStore; + private TemplateInfo templateInfo; + private Set/*<String>*/ allMacrosInProcesses; + private TemplateProcessHandler processHandler; + private String description; + private String label; + private String templateId; + private boolean fireDirtyEvents; + + /** + * Constructor + * + * @param templateInfo + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException + */ + + protected TemplateCore(TemplateInfo templateInfo) throws IOException, SAXException, ParserConfigurationException { + this.templateInfo = templateInfo; + templateDescriptor = new TemplateDescriptor(TemplateEngineHelper.getTemplateResourceURL(templateInfo.getPluginId(), templateInfo.getTemplatePath())); + valueStore = new ValueStore/*<String, String>*/(this); + valueStore.putAll(templateDescriptor.getTemplateDefaults(templateDescriptor.getRootElement())); + valueStore.putAll(TemplateEngine.getDefault().getSharedDefaults()); + valueStore.put("projectType", templateInfo.getProjectType()); //$NON-NLS-1$ + + processHandler = new TemplateProcessHandler(this); + allMacrosInProcesses = processHandler.getAllMacros(); + + fireDirtyEvents = true; + } + + /** + * Returns All Missing Macros In Processes. + * @return Set + */ + public Set/*<String>*/ getAllMissingMacrosInProcesses() { + Set/*<String>*/ set = new TreeSet/*<String>*/(allMacrosInProcesses); + if (set != null) { + for (Iterator iter = set.iterator(); iter.hasNext();) { + if (valueStore.get(iter.next()) != null) { + iter.remove(); + } + } + } + return set; + } + + /** + * return the ValueStore maintained by this Template. + * @return ValueStore. + */ + public Map/*<String, String>*/ getValueStore() { + return valueStore; + } + + /** + * This is the List of IDs from TemplateDescriptor with "attribute" Persist + * as "true" + * + * @return Vector of IDs. + */ + public List/*<String>*/ getPersistTrueIDs() { + return templateDescriptor.getPersistTrueIDs(); + } + + /** + * return the TemplateInfo instance corresponding to this Template. + * @return TemplateInfo. + */ + public TemplateInfo getTemplateInfo() { + return templateInfo; + } + + /** + * TemplateDescriptor for which, this Template is created. + */ + public TemplateDescriptor getTemplateDescriptor() { + return templateDescriptor; + } + + /** + * @return String, which contains the description + */ + public String getDescription() { + if (description == null) { + description = templateDescriptor.getRootElement().getAttribute(DESCRIPTION).trim(); + } + return description; + } + + /** + * @return String, which contains the id of the template + */ + public String getTemplateId() { + if (templateId == null) { + templateId = templateDescriptor.getRootElement().getAttribute(ID).trim(); + } + return templateId; + } + + /** + * @return String, which contains the Label + */ + public String getLabel() { + if (label == null) { + label = templateDescriptor.getRootElement().getAttribute(LABEL).trim(); + } + return label; + } + + /** + * TemplateDescriptor for which, this Template is created. + */ + public TemplateProcessHandler getProcessHandler() { + return processHandler; + } + + public String toString() + { + return getLabel(); + } + /** + * sets Dirty + * + */ + public void setDirty() { + if (fireDirtyEvents) { + synchronized (templateCache) { + templateCache.remove(templateInfo); + } + } + } + + /** + * initializeProcessBlockList() will create the ProcessBlockList, + * processPorcessBlockList() will invoke each process execution by assigning + * resources to each process (Ref. ProcessResourceManager). + * @param monitor + */ + public IStatus[] executeTemplateProcesses(IProgressMonitor monitor, final boolean showError) { + setDirty(); + TemplateEngine.getDefault().updateSharedDefaults(this); + final IStatus[][] result = new IStatus[1][]; + try { + result[0] = getProcessHandler().processAll(monitor); + } catch (ProcessFailureException e) { + TemplateEngineUtil.log(e); + result[0] = new IStatus[] {new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e)}; + } + return result[0]; + } + + /** + * Gets the Template + * + * @param templateInfo + * @throws IOException + * @throws ProcessFailureException + * @throws SAXException + * @throws ParserConfigurationException + * + * @since 4.0 + */ + public static TemplateCore getTemplate(TemplateInfo templateInfo) throws IOException, ProcessFailureException, SAXException, ParserConfigurationException { + synchronized (templateCache) { + TemplateCore template = (TemplateCore) templateCache.get(templateInfo); + if (template == null) { + template = new TemplateCore(templateInfo); + templateCache.put(templateInfo, template); + } + return template; + } + } + + private static class ValueStore/*<K, V>*/ extends HashMap/*<K, V>*/ { + private static final long serialVersionUID = -4523467333437879406L; + private TemplateCore template; + + ValueStore(TemplateCore template) { + this.template = template; + } + + public Object/*V*/ put(Object/*K*/ key, Object/*V*/ value) { + Object/*V*/ v = super.put(key, value); + template.setDirty(); + return v; + } + + public void putAll(Map/*<? extends K, ? extends V>*/ map) { + super.putAll(map); + template.setDirty(); + } + + public Object/*V*/ remove(Object key) { + Object/*V*/ v = super.remove(key); + template.setDirty(); + return v; + } + + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateDescriptor.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateDescriptor.java new file mode 100644 index 00000000000..bacec4f40ad --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateDescriptor.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + + +/** + * This class contains methods to get first process block element, next process block + * element and checks for next process block element. + */ +public class TemplateDescriptor { + public static final String PROPERTY_GROUP = "property-group"; //$NON-NLS-1$ + public static final String PROCESS = "process"; //$NON-NLS-1$ + public static final String IF = "if"; //$NON-NLS-1$ + public static final String ID = "id"; //$NON-NLS-1$ + public static final String DEFAULT = "default"; //$NON-NLS-1$ + public static final String PERSIST = "persist"; //$NON-NLS-1$ + public static final String BOOL_TRUE = "true"; //$NON-NLS-1$ + + private Document document; + private Element rootElement; + private List/*<String>*/ persistVector; + + /** + * Constructor which construct the Document based the URL + * @param descriptorURL + * @throws SAXException + * @throws IOException + * @throws ParserConfigurationException + */ + public TemplateDescriptor(URL descriptorURL) throws SAXException, IOException, ParserConfigurationException { + document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(descriptorURL.openStream()); + rootElement = document.getDocumentElement(); + persistVector = new ArrayList/*<String>*/(); + } + + /** + * This method is to get the default key value pair (HashMap) form template + * descriptor root element. + * + * @return default values with keys + */ + public Map/*<String, String>*/ getTemplateDefaults(Element rootElement) { + Map/*<String, String>*/ templateDefaults = new HashMap/*<String, String>*/(); + Element propertyGroupElement; + List/*<Element>*/ children = TemplateEngine.getChildrenOfElement(rootElement); + for (int i = 0, l = children.size(); i < l; i++) { + propertyGroupElement = (Element) children.get(i); + if (isNestedElement(propertyGroupElement)) { + templateDefaults = getTemplateDefaults(propertyGroupElement); + } + propertyElements(templateDefaults, propertyGroupElement); + } + return templateDefaults; + } + + /** + * Checks whether element nested or not + * @param element + * @return + */ + private boolean isNestedElement(Element element){ + boolean result=false; + if (element!=null){ + List/*<Element>*/ children = TemplateEngine.getChildrenOfElement(element); + String elementName = element.getNodeName(); + Element testElement; + String testElementName = null; + if (children.size() > 0){ + testElement = (Element) children.get(0); + testElementName=testElement.getNodeName(); + } + if(elementName.equals(testElementName)) + result=true; + else result=false; + } + return result; + } + + /** + * This method is to get the list of property-group elements from template + * descriptor root element + * + * @param aRootElement + * root element of type JDOM Element + * @return list of property-group elements + */ + public List getPropertyGroupList() { + List resultList = null; + List/*<Element>*/ list = new ArrayList/*<Element>*/(); + resultList = list; + if (rootElement != null) { + List/*<Element>*/ tempList = TemplateEngine.getChildrenOfElement(rootElement); + for (int i = 0, l = tempList.size(); i < l; i++) { + Element nextPropertyGroup = (Element) tempList.get(i); + String nextPGName = nextPropertyGroup.getNodeName(); + if (nextPGName.equalsIgnoreCase(PROPERTY_GROUP)) { + list.add(nextPropertyGroup); + } + } + } + return resultList; + } + + /** + * This mehtod is to get the complex property-group from template descriptor + * root element. complex means a property-group contains other + * property-group(s) + * + * @param rootElement + * root element of type JDOM Element + * @return porperty-group root element of type JDOM Element + */ + public Element getRootPropertyGroup(Element rootElement) { + if (rootElement != null) { + String rootElementName = rootElement.getNodeName(); + if (rootElementName.equalsIgnoreCase(PROPERTY_GROUP) && isNestedElement(rootElement)) { + return rootElement; + } + return rootElement; + } else { + String nextPGElementName = null; + List/*<Element>*/ propertyGroupList = TemplateEngine.getChildrenOfElement(rootElement); + for (int i = 0, l = propertyGroupList.size(); i < l; i++) { + Element nextPGElement = (Element) propertyGroupList.get(i); + if (isNestedElement(nextPGElement)) + nextPGElementName = nextPGElement.getNodeName(); + if (nextPGElementName.equalsIgnoreCase(PROPERTY_GROUP) && isNestedElement(nextPGElement)) { + return nextPGElement; + } + } + } + return null; + } + + /** + * This private method is used in getTemplateDefaults() to get defaults from + * property elements + * + * @param defaults + * HashMap to store deraults + * @param propertyGroupElement + * traverse the complex property-group element + */ + private void propertyElements(Map/*<String, String>*/ defaults, Element propertyGroupElement) { + List/*<Element>*/ children = TemplateEngine.getChildrenOfElement(propertyGroupElement); + for (int i = 0, l = children.size(); i < l; i++) { + Element propertyElement = (Element) children.get(i); + String key = propertyElement.getAttribute(ID); + String value = propertyElement.getAttribute(DEFAULT); + if (key != null && !key.equals("")) { + defaults.put(key, value); + } + + String persist = propertyElement.getAttribute(PERSIST); + if ((persist != null) && (persist.trim().equalsIgnoreCase(BOOL_TRUE))) { + persistVector.add(key); + } + } + } + + /** + * added to return root of this document. + */ + public Element getRootElement() { + return rootElement; + } + + /** + * return the list of IDs whose Persist attribute is true. + * + * @return Vector. + */ + public List/*<String>*/ getPersistTrueIDs() { + return persistVector; + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngine.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngine.java new file mode 100644 index 00000000000..dea101fe822 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngine.java @@ -0,0 +1,344 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.Platform; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * TemplateEngine is implemented as a Singleton. TemplateEngine is responsible for + * creating SharedDefaults and initializing the SharedDefaults. Template instances + * are obtained from TemplateEngine. + * + * @since 4.0 + */ +public class TemplateEngine { + + public static String TEMPLATES_EXTENSION_ID = CCorePlugin.PLUGIN_ID + ".templates"; //$NON-NLS-1$ + + /** + * static reference to the Singleton TemplateEngine instance. + */ + private static TemplateEngine TEMPLATE_ENGINE = new TemplateEngine(); + + /** + * This is a Map <WizardID, TemplateInfo>. + */ + private Map/*<String, List<TemplateInfo>>*/ templateInfoMap; + + /** + * TemplateEngine constructor, create and initialize SharedDefaults. + */ + private TemplateEngine() { + templateInfoMap = new HashMap/*<String, List<TemplateInfo>>*/(); + initializeTemplateInfoMap(); + } + + /** + * get All the templates, no filtering is done. + * + * @return + */ + public TemplateCore[] getTemplates() { + TemplateInfo[] templateInfoArray = getTemplateInfos(); + List/*<Template>*/ templatesList = new ArrayList/*<Template>*/(); + for (int i=0; i<templateInfoArray.length; i++) { + TemplateInfo info = templateInfoArray[i]; + try { + templatesList.add(TemplateCore.getTemplate(info)); + } catch (Exception e) { + } + } + return (TemplateCore[]) templatesList.toArray(new TemplateCore[templatesList.size()]); + } + + /** + * This method will be called by Contianer UIs (Wizard, PropertyPage, + * PreferencePage). Create a Template instance, update the ValueStore, with + * SharedDefaults. This method calls the getTemplate(URL), after getting URL + * for the given String TemplateDescriptor. + * + * @param StringTemplateDescriptor, + * TemplateDescriptor name. + * @throws IOException + */ + public TemplateCore getFirstTemplate(String projectType) { + return getFirstTemplate(projectType, null, null); + } + + public TemplateCore getFirstTemplate(String projectType, String toolChain, String usageFilter) { + try { + return TemplateCore.getTemplate(getTemplateInfos(projectType, toolChain, usageFilter)[0]); + } catch (Exception e) { + // ignore + } + return null; + } + + /** + * This method will be called by Contianer UIs (Wizard, PropertyPage, + * PreferencePage). Create a Template instance, update the ValueStore, with + * SharedDefaults. This method calls the getTemplate(URL), after getting URL + * for the given String TemplateDescriptor. + */ + public TemplateCore[] getTemplates(String projectType, String toolChain, String usageFilter) { + TemplateInfo[] templateInfoArray = getTemplateInfos(projectType, toolChain, usageFilter); + List/*<Template>*/ templatesList = new ArrayList/*<Template>*/(); + for (int i=0; i<templateInfoArray.length; i++) { + TemplateInfo info = templateInfoArray[i]; + try { + templatesList.add(TemplateCore.getTemplate(info)); + } catch (Exception e) { + } + } + return (TemplateCore[]) templatesList.toArray(new TemplateCore[templatesList.size()]); + } + + public TemplateCore[] getTemplates(String projectType, String toolChain) { + return getTemplates(projectType, toolChain, null); + } + + public TemplateCore[] getTemplates(String projectType) { + return getTemplates(projectType, null); + } + + public TemplateCore getTemplateById(String templateId) { + TemplateCore[] templates = getTemplates(); + + for(int i=0; i<templates.length; i++) { + TemplateCore template = templates[i]; + if (template.getTemplateId().equalsIgnoreCase(templateId)) { + return template; + } + } + return null; + } + + /** + * return the SharedDefaults. + * + * @return + */ + public Map/*<String, String>*/ getSharedDefaults() { + return SharedDefaults.getInstance().getSharedDefaultsMap(); + } + + /** + * update The SharedDefaults Map. This method will be called by Container + * UIs. After collecting data from UIPages, the IDs with Persist attribute + * as true, has to be persisted in SharedDefaults XML. For the same this + * method is called by passing the ValueStore(updated with user entered + * values). Get the PersistTrueIDs from TemplateDescriptor. Persist the + * values of IDs in ValueStore, which are also present in PersistTrueIDs + * vector. + * @param template + * @param aSharedValue + */ + public void updateSharedDefaults(TemplateCore template) { + Map/*<String, String>*/ tobePersisted = new HashMap/*<String, String>*/(); + Map/*<String, String>*/ valueStore = template.getValueStore(); + + for (Iterator i = template.getPersistTrueIDs().iterator(); i.hasNext();) { + String key = (String) i.next(); + tobePersisted.put(key, valueStore.get(key)); + } + SharedDefaults.getInstance().updateShareDefaultsMap(tobePersisted); + } + + /** + * create the singleton instance, check for null condition of + * TEMPLATE_ENGINE. If TEMPLATE_ENGINE is null create the TemplateEngine + * instance assign it to TEMPLATE_ENGINE. There is no need to have + * synchronized here(while creating TemplateEngine). + * + * @return TEMPLATE_ENGINE, instance of TemplateEngine. + * + * @since 4.0 + */ + public static TemplateEngine getDefault() { + return TEMPLATE_ENGINE; + } + + /** + * From the extension point take the class implementing the required + * functionality. Update the local HashMap of page-id and URL. This is for + * extension point "templates" + */ + private void initializeTemplateInfoMap() { + String location = null; + String pluginId = null; + String projectType = null; + String filterPattern = null; + String usage = null; + boolean isCategory = false; + String extraPagesProvider = null; + + IExtension[] extensions = Platform.getExtensionRegistry().getExtensionPoint(TEMPLATES_EXTENSION_ID).getExtensions(); + for(int i=0; i<extensions.length; i++) { + IExtension extension = extensions[i]; + IConfigurationElement[] configElements = extension.getConfigurationElements(); + pluginId = extension.getNamespaceIdentifier(); // Plugin-id of the extending plugin. + for(int j=0; j<configElements.length; j++) { + IConfigurationElement config = configElements[j]; + location = config.getAttribute(TemplateEngineHelper.LOCATION); + projectType = config.getAttribute(TemplateEngineHelper.PROJECT_TYPE); + filterPattern = config.getAttribute(TemplateEngineHelper.FILTER_PATTERN); + usage = config.getAttribute(TemplateEngineHelper.USAGE_DESCRIPTION); + isCategory = Boolean.valueOf(config.getAttribute(TemplateEngineHelper.IS_CATEGORY)).booleanValue(); + extraPagesProvider = config.getAttribute(TemplateEngineHelper.EXTRA_PAGES_PROVIDER); + + IConfigurationElement[] toolChainConfigs = config.getChildren(TemplateEngineHelper.TOOL_CHAIN); + Set toolChainIdSet = new HashSet(); + for (int k=0; k < toolChainConfigs.length; k++) { + toolChainIdSet.add(toolChainConfigs[k].getAttribute(TemplateEngineHelper.ID)); + } + + TemplateInfo templateInfo = new TemplateInfo(projectType, filterPattern, location, + pluginId, toolChainIdSet, + usage, extraPagesProvider, isCategory); + if (!templateInfoMap.containsKey(projectType)) { + templateInfoMap.put(projectType, new ArrayList/*<TemplateInfo>*/()); + } + ((List/*<TemplateInfo>*/)templateInfoMap.get(projectType)).add(templateInfo); + } + } + } + + /** + * Gets an array of template info objects matching the criteria passed as params. + */ + public TemplateInfo[] getTemplateInfos(String projectType, String toolChain, String usageFilter) { + List/*<TemplateInfo>*/ templateInfoList = (List/*<TemplateInfo*/) templateInfoMap.get(projectType.trim()); + List/*<TemplateInfo>*/ matchedTemplateInfoList = new ArrayList/*<TemplateInfo>*/(); + + if (templateInfoList != null) { + for (Iterator i = templateInfoList.iterator(); i.hasNext(); ) { + TemplateInfo templateInfo = (TemplateInfo) i.next(); + String filterPattern = templateInfo.getFilterPattern(); + String[] toolChains = templateInfo.getToolChainIds(); + + if (toolChain != null) { + for (int j=0; j < toolChains.length; j++) { + if (toolChains[j].equals(toolChain)) { + if (usageFilter != null && filterPattern.matches(usageFilter)) { + matchedTemplateInfoList.add(templateInfo); + } else if (usageFilter == null) { + matchedTemplateInfoList.add(templateInfo); + } + continue; + } + } + } else { + if (usageFilter != null && filterPattern.matches(usageFilter)) { + matchedTemplateInfoList.add(templateInfo); + } else if (usageFilter == null) { + matchedTemplateInfoList.add(templateInfo); + } + } + } + } + return (TemplateInfo[]) matchedTemplateInfoList.toArray(new TemplateInfo[matchedTemplateInfoList.size()]); + } + + public TemplateInfo[] getTemplateInfos(String projectType, String toolChain) { + return getTemplateInfos(projectType, toolChain, null); + } + + public TemplateInfo[] getTemplateInfos(String projectType) { + return getTemplateInfos(projectType, null, null); + } + + public TemplateInfo[] getTemplateInfos() { + List/*<TemplateInfo>*/ infoList = new ArrayList/*<TemplateInfo>*/(); + for (Iterator i = templateInfoMap.values().iterator(); i.hasNext();) { + infoList.addAll((List/*<TemplateInfo>*/)i.next()); + } + + return (TemplateInfo[]) infoList.toArray(new TemplateInfo[infoList.size()]); + } + + + /** + * Getter for templateInfoMap + * + * @return + */ + public Map/*<String, List<TemplateInfo>>*/ getTemplateInfoMap() { + return templateInfoMap; + } + + /** + * Returns the Template Schema URL + * + * @return URL of the Template Schema. + * @throws IOException + */ + public URL getTemplateSchemaURL() throws IOException { + return FileLocator.toFileURL(Platform.getBundle(CCorePlugin.PLUGIN_ID).getEntry("schema/TemplateDescriptorSchema.xsd")); //$NON-NLS-1$ + } + + /** + * Returns the Children of the Element. + * @param element + * @return List of the child elelments + * + * @since 4.0 + */ + public static List/*<Element>*/ getChildrenOfElement(Element element) { + List/*<Element>*/ list = new ArrayList/*<Element>*/(); + NodeList children = element.getChildNodes(); + for (int i = 0, l = children.getLength(); i < l; i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + list.add((Element) child); + } + } + return list; + } + + /** + * Returns the child elements by Tag + * + * @param element + * @param tag + * @return List of child elements + * + * @since 4.0 + */ + public static List/*<Element>*/ getChildrenOfElementByTag(Element element, String tag) { + List/*<Element>*/ list = new ArrayList/*<Element>*/(); + NodeList children = element.getChildNodes(); + for (int i = 0, l = children.getLength(); i < l; i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(tag)) { + list.add((Element) child); + } + } + return list; + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineHelper.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineHelper.java new file mode 100644 index 00000000000..1866acdba6b --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineHelper.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; + +/** + * Acts as an Helper class for Template Engine + * + * @since 4.0 + */ +public class TemplateEngineHelper { + + public static final String OPEN_MARKER = "$("; //$NON-NLS-1$ + public static final String CLOSE_MARKER = ")"; //$NON-NLS-1$ + public static final String LOGGER_FILE_NAME = "Process"; //$NON-NLS-1$ + // This is used while getting the Plugin Path. + public static final String PROJRESOURCE = "plugin.xml"; //$NON-NLS-1$ + public static final String BOOLTRUE = "true"; //$NON-NLS-1$ + public static final String ID = "id"; //NON-NLS-1$ + public static final String VALUE = "value"; //NON-NLS-1$ + public static final String SDLOG_FILE_NAME = "sharedDefaults"; //$NON-NLS-1$ + public static final String LOCATION = "location"; //NON-NLS-1$ + public static final String WIZARD_ID = "wizardId"; //NON-NLS-1$ + public static final String FILTER_PATTERN = "filterPattern"; //NON-NLS-1$ + public static final String USAGE_DESCRIPTION = "usageDescription"; //NON-NLS-1$ + public static final String PROJECT_TYPE = "projectType"; //NON-NLS-1$ + public static final String TOOL_CHAIN = "toolChain"; //NON-NLS-1$ + public static final String EXTRA_PAGES_PROVIDER = "pagesAfterTemplateSelectionProvider"; //NON-NLS-1$ + public static final String IS_CATEGORY = "isCategory"; //NON-NLS-1$ + public static final String CONFIGURATIONS = "Configurations"; //NON-NLS-1$ + + /** + * Gets the backup shareddefaults XML file. Presence of the file indicates + * that the template engine or the application underwent some crash or + * destruction. + * + * @param sharedLocation + * @return sharedXMLFile + * + * @since 4.0 + */ + + public static File getSharedDefaultLocation(String sharedLocation) { + + File sharedXMLFile = findLocation(sharedLocation); + return sharedXMLFile; + } + + /** + * Finds the location of the shareddefaults backup and original xml file. + * + * @param fileLocation + * @return file + * + * @since 4.0 + */ + + private static File findLocation(String fileLocation) { + + Plugin plugin = CCorePlugin.getDefault(); + IPath stateLoc = plugin.getStateLocation(); + fileLocation = stateLoc.toString() + File.separator + fileLocation; + File file = new File(fileLocation); + + return file; + } + + /** + * Stores the shareddefaults xml file in + * "${workspace}/.metadata/.plugins/${plugin.name}/shareddefaults.xml" path. + * + * @param sharedLocation + * @return sharedXMLFile + * + * @since 4.0 + */ + + public static File storeSharedDefaultLocation(String sharedLocation) { + + File sharedXMLFile = findLocation(sharedLocation); + + try { + createNewFile(sharedXMLFile.getPath()); + } catch (IOException e) { + e.printStackTrace(); + } + return sharedXMLFile; + } + + /** + * This creates a new File, in the Absolute Path given as argument. The File + * name will be part of the path argument. + * + * @param aFileName, + * absoulute File path(including File name) to be created. + * + * @since 4.0 + */ + public static void createNewFile(String fileName) throws IOException { + + (new File(fileName)).createNewFile(); + } + + /** + * This method returns the workspace path present in the workspace + * + * @return String Example : file:/C:/eclipse/workspace/ + * + * @since 4.0 + */ + public static IPath getWorkspacePath() { + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + IPath workSpacePath = new Path(root.getLocation().toString() + File.separator); + return workSpacePath; + + } + + /** + * given a String of the form $(ID), return ID. + * + * @param markerString + * @return + * + * @since 4.0 + */ + public static String getFirstMarkerID(String markerString) { + String key = null; + if (markerString.indexOf(OPEN_MARKER) != -1) { + key = markerString.substring(markerString.indexOf(OPEN_MARKER) + OPEN_MARKER.length(), markerString + .indexOf(CLOSE_MARKER)); + } + return key; + } + + /** + * Check whether there is a directory existing in present workspace, with + * the given name. + * + * @param directoryName + * @return true, if directory exists. + * + * @since 4.0 + */ + public static boolean checkDirectoryInWorkspace(String directoryName) { + + boolean retVal = false; + File file = null; + + try { + file = new File(getWorkspacePath() + directoryName); + } catch (Exception exp) { + + } + if ((file != null) && (file.exists()) && (file.isDirectory())) { + retVal = true; + } + return retVal; + } + /** + * Return Template Source path as URL + * @param pluginId + * @param resourcePath + * @return URL, of the Template Resource + * @throws IOException + * + * @since 4.0 + */ + + public static URL getTemplateResourceURL(String pluginId, String resourcePath) throws IOException { + return FileLocator.toFileURL(Platform.getBundle(pluginId).getEntry(resourcePath)); + } + + /** + * + * Returns the Template Resource Relative Path as URL + * @param template + * @param resourcePath + * @return URL, of the Template Resource + * @throws IOException + * + * @since 4.0 + */ + public static URL getTemplateResourceURLRelativeToTemplate(TemplateCore template, String resourcePath) throws IOException { + TemplateInfo templateInfo = template.getTemplateInfo(); + String path = templateInfo.getTemplatePath(); + int slash = path.lastIndexOf("/"); //$NON-NLS-1$ + if (slash == -1) { + path = resourcePath; + } else { + path = path.substring(0, slash + 1) + resourcePath; + } + URL entry = Platform.getBundle(templateInfo.getPluginId()).getEntry(path); + if (entry == null) { + return null; + } + return FileLocator.toFileURL(entry); + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineMessages.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineMessages.java new file mode 100644 index 00000000000..bba96d27340 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineMessages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class TemplateEngineMessages { + private static final String BUNDLE_NAME = "org.eclipse.cdt.core.templateengine.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private TemplateEngineMessages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineUtil.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineUtil.java new file mode 100644 index 00000000000..6802f700941 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateEngineUtil.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine; + +import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +public class TemplateEngineUtil { + + public static void log(Throwable t) { + if (t == null) { + return; + } + if (t instanceof InvocationTargetException) { + t = ((InvocationTargetException) t).getTargetException(); + } + if (t instanceof CoreException) { + ResourcesPlugin.getPlugin().getLog().log(((CoreException) t).getStatus()); + } if (t instanceof ProcessFailureException) { + do { + List/*<IStatus>*/ statuses = ((ProcessFailureException) t).getStatuses(); + if (statuses != null) { + for(Iterator i = statuses.iterator(); i.hasNext(); ) { + IStatus status = (IStatus) i.next(); + ResourcesPlugin.getPlugin().getLog().log(status); + } + } + t = t.getCause(); + } while (t != null && t instanceof ProcessFailureException); + } else { + ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, IStatus.OK, t.getMessage() == null ? t.toString() : t.getMessage() , t)); + } + } + +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateInfo.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateInfo.java new file mode 100644 index 00000000000..169b708964c --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/TemplateInfo.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine; + +import java.util.Set; + + + +/** + * TemplateInfo class contains the template information like wizard ID, pattern, path and project type. + */ +public class TemplateInfo { + private String projectTypeId; + private String filterPattern; + private String usageDescription; + private String templatePath; + private String pluginId; + private Set toolChainIdSet; + private String pagesProvider; + private boolean isCategory; + private String icon; + + public TemplateInfo(String projectTypeId, String filterPattern, String templatePath, + String pluginId, Set toolChainIdSet, String usageDescription, + String pagesProvider, boolean isCategory) { + this.filterPattern = filterPattern; + this.templatePath = templatePath; + this.pluginId = pluginId; + this.projectTypeId = projectTypeId; + this.toolChainIdSet = toolChainIdSet; + this.usageDescription = usageDescription != null ? usageDescription : ""; //$NON-NLS-1$ + this.pagesProvider = pagesProvider; + this.isCategory = isCategory; + } + + /** + * Returns the Plugin ID + * @return String contains the plugin id. + */ + public String getPluginId() { + return pluginId; + } + + /** + * Returns the Template path as String. + * @return String containing the path. + */ + public String getTemplatePath() { + return templatePath; + } + + /** + * Returns the Filter Pattern. + * @return String containing the Filter Pattern. + */ + public String getFilterPattern() { + return filterPattern; + } + + /** + * @return the usageDescription + */ + public String getUsageDescription() { + return usageDescription; + } + + public String getExtraPagesProvider() { + return pagesProvider; + } + + /** + * @return the projectTypeIds + */ + public String getProjectType() { + return projectTypeId; + } + + /** + * @return the toolChainIds + */ + public String[] getToolChainIds() { + return (String[]) toolChainIdSet.toArray(new String[toolChainIdSet.size()]); + } + + /** + * @return the isCategory + */ + public boolean isCategory() { + return isCategory; + } + + /** + * @return the icon image file name + */ + public String getIcon() { + return icon; + } + + /** + * Checks whether two TemplateInfo object are equal. + */ + public boolean equals(Object obj) { + if (obj instanceof TemplateInfo) { + TemplateInfo info = (TemplateInfo) obj; + return projectTypeId.equals(info.projectTypeId) && templatePath.equals(info.templatePath) && pluginId.equals(info.pluginId) + && (((filterPattern == null || info.filterPattern == null) && filterPattern == info.filterPattern) + || filterPattern.equals(info.filterPattern)) + && ((toolChainIdSet.equals(info.toolChainIdSet))) + && ((isCategory == info.isCategory)); + } + return false; + } + + /** + * Return the hashcode of the object. + */ + public int hashCode() { + return projectTypeId.hashCode() | templatePath.hashCode() | pluginId.hashCode(); + } + +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/messages.properties b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/messages.properties new file mode 100644 index 00000000000..08fb3cac580 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/messages.properties @@ -0,0 +1,31 @@ +############################################################################### +# Copyright (c) 2007 Symbian Software Limited 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: +# Bala Torati (Symbian) - Initial API and implementation +############################################################################### + +TemplateEngine.internalError=Internal Error: +TemplateEngine.templateEngine=Template Engine +ProjectCreatedActions.InsufficientInformation=Insufficient information to create new project + +ConditionalProcessGroup.notExecuting=Condition block not executing: +ConditionalProcessGroup.unexpandableMacro=Condition has an unexpandable macro: +Process.argument=Argument +Process.expandableMacro=\ has an unexpandable macro: +Process.error=-->Error: +Process.success=-->Success: +Process.info=-->Info: +Process.unknownProcess=Unknown process: +Process.executedSuccessfully=Executed successfully with args: +ProcessRunner.unexpectedArguments=Unexpected arguments found. +ProcessRunner.missingArguments=Missing arguments. +ProcessRunner.argumentsMismatch=Argument type mismatch: +ProcessRunner.error=-->Error: +ProcessRunner.success=-->Success: +ProcessRunner.info=-->Info: +ProcessHelper.fileNotFound=File not found: diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ConditionalProcessGroup.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ConditionalProcessGroup.java new file mode 100644 index 00000000000..f3f59406f48 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ConditionalProcessGroup.java @@ -0,0 +1,284 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateDescriptor; +import org.eclipse.cdt.core.templateengine.TemplateEngine; +import org.eclipse.cdt.core.templateengine.TemplateEngineMessages; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.w3c.dom.Element; + + +/** + * ConditionalProcess encloses an <if condition="..."></if> block of the template. + * The currently supported conditions are equals and not equals operations performed on two + * Strings. The respective operators are == and !=. Any spaces will be treated as part of the + * operands. The two operands will be evaluated for simple String equals and not equals after + * performing a single pass replace of any replace markers with their values in the template's + * value store. + */ +public class ConditionalProcessGroup { + + private TemplateCore template; + private Set/*<String>*/ macros; + private String conditionString; + private String lValue; + private String rValue; + private Operator op; + private List/*<Process>*/ processes; + private String id; + + /** + * @author BalaT + */ + private static class Operator { + final static Operator EQUALS = new Operator("="); //$NON-NLS-1$ + final static Operator NOT_EQUALS = new Operator("!="); //$NON-NLS-1$ + + String id; + Operator(String id) { + this.id = id; + } + public boolean equals(Object arg0) { + if(arg0 instanceof Operator) { + return id.equals(((Operator)arg0).id); + } + return false; + } + } + + /** + * Constructs a ConditionalProcess element from the supplied conditionElement (<if>) while building Process + * objects out of each of the element's <process> children. + * @throws ProcessFailureException + */ + public ConditionalProcessGroup(TemplateCore template, Element conditionElement, int id) { + this.id = "Condition " + id; //$NON-NLS-1$ + conditionString = conditionElement.getAttribute(ProcessHelper.CONDITION); + if (conditionString != null) { + if (conditionString.trim().equals("")) { //$NON-NLS-1$ + conditionString = null; + } else { + int op = conditionString.indexOf(ProcessHelper.EQUALS); + if (op != -1) { + this.op = Operator.EQUALS; + lValue = conditionString.substring(0, op); + rValue = conditionString.substring(op + ProcessHelper.EQUALS.length()); + } else { + op = conditionString.indexOf(ProcessHelper.NOT_EQUALS); + if (op != -1) { + this.op = Operator.NOT_EQUALS; + lValue = conditionString.substring(0, op); + rValue = conditionString.substring(op + ProcessHelper.NOT_EQUALS.length()); + }//else an unsupported operation where this condition is ignored. + } + collectMacros(lValue); + collectMacros(rValue); + } + } + createProcessObjects(template, TemplateEngine.getChildrenOfElementByTag(conditionElement, TemplateDescriptor.PROCESS)); + } + + /** + * Adds values passed as parameter to the macros object + * @param value + */ + private void collectMacros(String value) { + if (value != null) { + if (macros == null) { + macros = new HashSet/*<String>*/(); + } + macros.addAll(ProcessHelper.getReplaceKeys(value)); + } + } + + /** + * Constructs a ConditionalProcess element from the supplied process elements while building Process + * objects out of each of the supplied process elements (<process>). The condition in this case is evaluated to true. + * + * This Constructor is expected to be used to evaluate all those process elements that are children of the template root element. + * @throws ProcessFailureException + */ + public ConditionalProcessGroup(TemplateCore template, Element[] processElements) { + id = "No Condition"; //$NON-NLS-1$ + createProcessObjects(template, Arrays.asList(processElements)); + } + + /** + * Creates the Proccess from the process Elements. + * @param template + * @param processElements + */ + private void createProcessObjects(TemplateCore template, List/*<Element>*/ processElements) { + this.template = template; + this.processes = new ArrayList/*<Process>*/(processElements.size()); + for (int j = 0, l = processElements.size(); j < l; j++) { + Element processElem = (Element) processElements.get(j); + if (processElem.getNodeName().equals(TemplateDescriptor.PROCESS)) { + String processId = id + "--> Process " + (j + 1) + " (" + processElem.getAttribute(Process.ELEM_TYPE) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + processes.add(new Process(template, processElem, processId)); + } + } + } + + /** + * Checks if this conditional process group is completely ready to be processed. + */ + public boolean isReadyToProcess() { + return areMacrosForConditionEvaluationExpandable() && isConditionValueTrue() && areProcessesReady(); + } + + /** + * + * @return boolean, as true if the Processes are ready to process + */ + private boolean areProcessesReady() { + for(Iterator i = processes.iterator(); i.hasNext(); ) { + Process process = (Process) i.next(); + if (!process.isReadyToProcess()) { + return false; + } + } + return true; + } + + /** + * + * @return boolean, true if Macros For Condition Evaluation Expandable. + */ + private boolean areMacrosForConditionEvaluationExpandable() { + if (macros != null) { + Map/*<String, String>*/ valueStore = template.getValueStore(); + for(Iterator i = macros.iterator(); i.hasNext(); ) { + String value = (String) i.next(); + if (valueStore.get(value) == null) { + return false; + } + } + } + return true; + } + + /** + * + * @return boolean, true if Condition Value is True. + */ + public boolean isConditionValueTrue() { + if (conditionString == null) { + return true; + } + if (!areMacrosForConditionEvaluationExpandable()) { + return false; + } + Map/*<String, String>*/ valueStore = template.getValueStore(); + String lValue = this.lValue; + String rValue = this.rValue; + for(Iterator i = macros.iterator(); i.hasNext(); ) { + String value = (String) i.next(); + lValue = lValue.replaceAll(ProcessHelper.START_PATTERN + value + ProcessHelper.END_PATTERN, (String) valueStore.get(value)); + rValue = rValue.replaceAll(ProcessHelper.START_PATTERN + value + ProcessHelper.END_PATTERN, (String) valueStore.get(value)); + } + if(op.equals(Operator.EQUALS)) { + return lValue.equals(rValue); + } else if(op.equals(Operator.NOT_EQUALS)) { + return !lValue.equals(rValue); + } else { + return false; + } + } + + /** + * Process and Returns the Status of the prosses as a List. + * @param monitor + * @return List contains the IStatus. + * @throws ProcessFailureException + */ + public List/*<IStatus>*/ process(IProgressMonitor monitor) throws ProcessFailureException { + if (!areMacrosForConditionEvaluationExpandable()) { + throw new ProcessFailureException(getUnexpandableMacroMessage()); + } + if (!isConditionValueTrue()) { + List/*<IStatus>*/ statuses = new ArrayList/*<IStatus>*/(1); + statuses.add(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, IStatus.INFO, TemplateEngineMessages.getString("ConditionalProcessGroup.notExecuting") + id, null)); //$NON-NLS-1$ + return statuses; + } + List/*<IStatus>*/ statuses = new ArrayList/*<IStatus>*/(processes.size()); + for(Iterator i = processes.iterator(); i.hasNext(); ) { + Process process = (Process) i.next(); + try { + statuses.add(process.process(monitor)); + } catch (ProcessFailureException e) { + throw new ProcessFailureException(e.getMessage(), e, statuses); + } + } + return statuses; + } + + /** + * Return the Unexpandable Macro Message + * @return + */ + private String getUnexpandableMacroMessage() { + if (macros != null) { + Map/*<String, String>*/ valueStore = template.getValueStore(); + for(Iterator i = macros.iterator(); i.hasNext(); ) { + String value = (String) i.next(); + if (valueStore.get(value) == null) { + return TemplateEngineMessages.getString("ConditionalProcessGroup.unexpandableMacro") + value; //$NON-NLS-1$ + } + } + } + return null; + } + + /** + * Returns the Macros as a Set. + * @return Set, contains macros + */ + public Set/*<String>*/ getMacros() { + return macros; + } + + /** + * Returns All Macros as a Set. + * @return Set, contains macros + */ + public Set/*<String>*/ getAllMacros() { + Set/*<String>*/ set = null; + if (macros != null) { + set = new HashSet/*<String>*/(); + set.addAll(macros); + } + for(Iterator i = processes.iterator(); i.hasNext(); ) { + Process process = (Process) i.next(); + Set/*<String>*/ subSet = process.getMacros(); + if (subSet != null) { + if (set == null) { + set = new HashSet/*<String>*/(); + } + set.addAll(subSet); + } + } + return set; + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/Process.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/Process.java new file mode 100644 index 00000000000..cad1c6e38a5 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/Process.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateEngine; +import org.eclipse.cdt.core.templateengine.TemplateEngineMessages; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.w3c.dom.Element; + + +/** + * This class contains methods to get first process block element, next process + * block element and checks for next process block element. + */ +public class Process { + public static final String ELEM_TYPE = "type"; //$NON-NLS-1$ + + private ProcessRunner processRunner; + private ProcessArgument[] args; + private TemplateCore template; + private String id; + private String processType; + + /** + * Constructor to create a process. + * @param template + * @param element + * @param id + */ + public Process(TemplateCore template, Element element, String id) { + this.template = template; + this.id = id; + processType = element.getAttribute(ELEM_TYPE); + processRunner = ProcessRunnerFactory.getDefault().getProcessRunner(processType); + if (processRunner != null) { + buildArgs(template, element); + } + } + + /** + * This method build the necessary Arguments for the process + * @param template + * @param element + */ + private void buildArgs(TemplateCore template, Element element) { + List/*<Element>*/ children = TemplateEngine.getChildrenOfElement(element); + ProcessParameter[] params = processRunner.getProcessParameters(); + List/*<ProcessArgument>*/ list = new ArrayList/*<ProcessArgument>*/(params.length); + int childIndex = 0; + for(int i=0; i<params.length; i++) { + ProcessParameter param = params[i]; + boolean childrenRemain = childIndex < children.size(); + Element child = (Element) (childrenRemain ? children.get(childIndex) : null); + if (param.isExternal() && (!childrenRemain || !param.getName().equals(child.getAttribute(ProcessArgument.ELEM_NAME)))) { + list.add(new ProcessArgument(template, param)); + } else if (childrenRemain) { + list.add(new ProcessArgument(template, child)); + childIndex++; + } + } + while (childIndex < children.size()) { + list.add(new ProcessArgument(template, (Element) children.get(childIndex++))); + } + args = (ProcessArgument[]) list.toArray(new ProcessArgument[list.size()]); + } + + /** + * + * @return boolean, true if the Process is Ready. + */ + public boolean isReadyToProcess() { + if (processRunner == null || !processRunner.areArgumentsMatchingRequiredParameters(args) || !areAllMacrosExpandable()) { + return false; + } + return true; + } + + /** + * + * @return boolean, true if Macros are Exapandable. + */ + private boolean areAllMacrosExpandable() { + if (args != null) { + for(int i=0; i<args.length; i++) { + ProcessArgument arg = args[i]; + if (!arg.areAllMacrosExpandable()) { + return false; + } + } + } + return true; + } + + /** + * Returns First NonExpandable Macro Message + */ + private String getFirstNonExpandableMacroMessage(ProcessArgument[] args2) { + if (args != null) { + String macro; + for(int i=0; i<args.length; i++) { + ProcessArgument arg = args[i]; + if ((macro = arg.getFirstNonExpandableMacro()) != null) { + return TemplateEngineMessages.getString("Process.argument") + arg.getName() + TemplateEngineMessages.getString("Process.expandableMacro") + macro; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + return null; + } + + /** + * Returns the Process Message depending on the parameters. + * @param code + * @param msg + * @return + */ + private String getProcessMessage(int code, String msg) { + switch (code) { + case IStatus.ERROR: + return id + TemplateEngineMessages.getString("Process.error") + msg; //$NON-NLS-1$ + case IStatus.OK: + return id + TemplateEngineMessages.getString("Process.success") + msg; //$NON-NLS-1$ + default: + return id + TemplateEngineMessages.getString("Process.info") + msg; //$NON-NLS-1$ + } + } + + /** + * Constructor + * @param monitor + * @return + * @throws ProcessFailureException + */ + public IStatus process(IProgressMonitor monitor) throws ProcessFailureException { + if (processRunner == null) { + throw new ProcessFailureException(TemplateEngineMessages.getString("Process.unknownProcess") + processType); //$NON-NLS-1$ + } + if (!processRunner.areArgumentsMatchingRequiredParameters(args)) { + throw new ProcessFailureException(processRunner.getArgumentsMismatchMessage(args)); + } + if (!areAllMacrosExpandable()) { + throw new ProcessFailureException(getProcessMessage(IStatus.ERROR, getFirstNonExpandableMacroMessage(args))); + } + resolve(); + processRunner.process(template, args, id, monitor); + return new Status(IStatus.INFO, CCorePlugin.PLUGIN_ID, IStatus.OK, getProcessMessage(IStatus.OK, TemplateEngineMessages.getString("Process.executedSuccessfully") + Arrays.asList(args)), null); //$NON-NLS-1$ + } + + private void resolve() { + if (args != null) { + for(int i=0; i<args.length; i++) { + ProcessArgument arg = args[i]; + if (!arg.isResolved()) { + arg.resolve(); + } + } + } + } + + /** + * Returns the Macros. + * @return + */ + public Set/*<String>*/ getMacros() { + Set/*<String>*/ set = null; + if (args != null) { + for(int i=0; i<args.length; i++) { + ProcessArgument arg = args[i]; + Set/*<String>*/ subSet = arg.getMacros(); + if (subSet != null) { + if (set == null) { + set = new HashSet/*<String>*/(); + } + set.addAll(subSet); + } + } + } + return set; + } + + public String toString() { + return id; + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessArgument.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessArgument.java new file mode 100644 index 00000000000..b5abbba0137 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessArgument.java @@ -0,0 +1,435 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateEngine; +import org.w3c.dom.Element; + + +/** + * ProcessArgument class responsible for constructing process Arguments by taking info from Template. + */ +public class ProcessArgument { + + static final String ELEM_NAME = "name"; //$NON-NLS-1$ + private static final String ELEM_VALUE = "value"; //$NON-NLS-1$ + private static final String ELEM_ELEMENT = "element"; //$NON-NLS-1$ + private static final String ELEM_SIMPLE = "simple"; //$NON-NLS-1$ + private static final String ELEM_SIMPLE_ARRAY = "simple-array"; //$NON-NLS-1$ + private static final String ELEM_COMPLEX = "complex"; //$NON-NLS-1$ + private static final String ELEM_COMPLEX_ARRAY = "complex-array"; //$NON-NLS-1$ + + private String name; + private byte type; + + private String simpleValue; + private String[] simpleValueArray; + private ProcessArgument[] complexValue; + private ProcessArgument[][] complexValueArray; + + private String resolvedSimpleValue; + private String[] resolvedSimpleValueArray; + + private TemplateCore template; + + private Set/*<String>*/ macros; + private boolean resolved; + private ProcessParameter externalParam; + + /** + * constructor + * @param template + * @param elem + */ + public ProcessArgument(TemplateCore template, Element elem) { + this.template = template; + this.name = elem.getAttribute(ELEM_NAME); + String elemName = elem.getNodeName(); + if (elemName.equals(ELEM_SIMPLE)) { + type = ProcessParameter.SIMPLE; + simpleValue = elem.getAttribute(ELEM_VALUE); + collectMacros(simpleValue); + } else if (elemName.equals(ELEM_SIMPLE_ARRAY)) { + type = ProcessParameter.SIMPLE_ARRAY; + List/*<Element>*/ valueElements = TemplateEngine.getChildrenOfElementByTag(elem, ELEM_ELEMENT); + simpleValueArray = new String[valueElements.size()]; + for (int i = 0, l = valueElements.size(); i < l; i++) { + simpleValueArray[i] = ((Element)valueElements.get(i)).getAttribute(ELEM_VALUE); + collectMacros(simpleValueArray[i]); + } + } else if (elemName.equals(ELEM_COMPLEX)) { + type = ProcessParameter.COMPLEX; + List/*<Element>*/ children = TemplateEngine.getChildrenOfElement(elem); + complexValue = new ProcessArgument[children.size()]; + for (int i = 0, l = children.size(); i < l; i++) { + complexValue[i] = new ProcessArgument(template, (Element) children.get(i)); + Set/*<String>*/ subMacros = complexValue[i].getMacros(); + if (macros == null) { + macros = new HashSet/*<String>*/(); + } + if (subMacros != null) { + macros.addAll(subMacros); + } + } + } else if (elemName.equals(ELEM_COMPLEX_ARRAY)) { + type = ProcessParameter.COMPLEX_ARRAY; + List/*<Element>*/ valueElements = TemplateEngine.getChildrenOfElementByTag(elem, ELEM_ELEMENT); + complexValueArray = new ProcessArgument[valueElements.size()][]; + + for (int i = 0, l = valueElements.size(); i < l; i++) { + List/*<Element>*/ children = TemplateEngine.getChildrenOfElement((Element)valueElements.get(i)); + complexValueArray[i] = new ProcessArgument[children.size()]; + for (int j = 0, l2 = children.size(); j < l2; j++) { + complexValueArray[i][j] = new ProcessArgument(template, (Element) children.get(j)); + Set/*<String>*/ subMacros = complexValueArray[i][j].getMacros(); + if (subMacros != null) { + if (macros == null) { + macros = new HashSet/*<String>*/(); + } + macros.addAll(subMacros); + } + } + } + } + } + + /** + * Creates an <i>external</i> argument. This is not read from the template descriptor. + * @param param The ProcessParameter whose replacement this argument is in the Process call + */ + public ProcessArgument(TemplateCore template, ProcessParameter param) { + this.template = template; + name = param.getName(); + type = param.getType(); + macros = new HashSet/*<String>*/(); + macros.add(name); + simpleValue = ProcessHelper.getReplaceMarker(name); + this.externalParam = param; + } + + /** + * Adds the marcos based on the value. + * @param value + */ + private void collectMacros(String value) { + if (value == null) { + return; + } + if (macros == null) { + macros = new HashSet/*<String>*/(); + } + macros.addAll(ProcessHelper.getReplaceKeys(value)); + } + + /** + * Returns Parameter name. + * @return parameter name as String + */ + public String getName() { + return name; + } + + /** + * Returns the Parameter Type + * @return the Parmeter Type as String + */ + public byte getParameterType() { + return type; + } + + /** + * Returns the Simple Value. + * @return String, + */ + public String getSimpleValue() { + return resolved ? resolvedSimpleValue : simpleValue; + } + + /** + * Returns the Simple Array Values. + * @return String Array. + */ + public String[] getSimpleArrayValue() { + return resolved ? resolvedSimpleValueArray : simpleValueArray; + } + + /** + * Returns Process Arguments + */ + public ProcessArgument[] getComplexValue() { + return complexValue; + } + + /** + * Returns Process Arguments + */ + public ProcessArgument[][] getComplexArrayValue() { + return complexValueArray; + } + + /** + * Check for parameter type. + * @param param + * @return boolean + */ + public boolean isOfParameterType(ProcessParameter param) { + if (param.getType() != type || !param.getName().equals(name)) { + return false; + } + switch (type) { + case ProcessParameter.SIMPLE: + return simpleValue != null || param.isNullable(); + case ProcessParameter.SIMPLE_ARRAY: + return true; + case ProcessParameter.COMPLEX: + ProcessParameter[] params = param.getComplexChildren(); + if (params.length != complexValue.length) { + return false; + } + for (int i = 0; i < complexValue.length; i++) { + if (!complexValue[i].isOfParameterType(params[i])) { + return false; + } + } + return true; + case ProcessParameter.COMPLEX_ARRAY: + params = param.getComplexChildren(); + for(int i=0; i<complexValueArray.length; i++) { + ProcessArgument[] complexValue = complexValueArray[i]; + if (params.length != complexValue.length) { + return false; + } + for (int j = 0; j < complexValue.length; j++) { + if (!complexValue[j].isOfParameterType(params[j])) { + return false; + } + } + } + return true; + } + return false; + } + + /** + * Returns true if All macros are Expandable. + * @return + */ + public boolean areAllMacrosExpandable() { + switch (type) { + case ProcessParameter.SIMPLE: + if (externalParam != null) { + return externalParam.isNullable() || template.getValueStore().get(name) != null; + } + case ProcessParameter.SIMPLE_ARRAY: + if (macros == null || macros.size() == 0) { + return true; + } + Map/*<String, String>*/ valueStore = template.getValueStore(); + for(Iterator i = macros.iterator(); i.hasNext(); ) { + String macro = (String) i.next(); + if (valueStore.get(macro) == null) { + return false; + } + } + return true; + case ProcessParameter.COMPLEX: + for(int i=0; i<complexValue.length; i++) { + ProcessArgument arg = complexValue[i]; + if (!arg.areAllMacrosExpandable()) { + return false; + } + } + return true; + case ProcessParameter.COMPLEX_ARRAY: + for(int i=0; i<complexValueArray.length; i++) { + ProcessArgument[] complexValue =complexValueArray[i]; + for(int j=0; j<complexValue.length; j++) { + ProcessArgument arg = complexValue[j]; + if (!arg.areAllMacrosExpandable()) { + return false; + } + } + } + return true; + } + return true; + } + + /** + * Returns the First Non-expandable Macro. + */ + public String getFirstNonExpandableMacro() { + switch (type) { + case ProcessParameter.SIMPLE: + case ProcessParameter.SIMPLE_ARRAY: + if (macros == null || macros.size() == 0) { + return null; + } + Map/*<String, String>*/ valueStore = template.getValueStore(); + for(Iterator i = macros.iterator(); i.hasNext(); ) { + String macro = (String) i.next(); + if (valueStore.get(macro) == null) { + return macro; + } + } + return null; + case ProcessParameter.COMPLEX: + String macro; + for(int i=0; i<complexValue.length; i++) { + ProcessArgument arg = complexValue[i]; + if ((macro = arg.getFirstNonExpandableMacro()) != null) { + return macro; + } + } + return null; + case ProcessParameter.COMPLEX_ARRAY: + for(int i=0; i<complexValueArray.length; i++) { + ProcessArgument[] complexValue =complexValueArray[i]; + for(int j=0; j<complexValue.length; j++) { + ProcessArgument arg = complexValue[j]; + if ((macro = arg.getFirstNonExpandableMacro()) != null) { + return macro; + } + } + } + return null; + } + return null; + } + + /** + * Returns the Macros as Set. + * @return Set, contains the Macros. + */ + public Set/*<String>*/ getMacros() { + return macros; + } + + /** + * resolve + * + */ + public void resolve() { + Map/*<String, String>*/ valueStore = template.getValueStore(); + switch (type) { + case ProcessParameter.SIMPLE: + if (externalParam != null) { + resolvedSimpleValue = (String) template.getValueStore().get(name); + } else { + resolvedSimpleValue = simpleValue; + if (macros != null && !macros.isEmpty()) { + resolvedSimpleValue = ProcessHelper.getValueAfterExpandingMacros(resolvedSimpleValue, macros, valueStore); + } + } + break; + case ProcessParameter.SIMPLE_ARRAY: + resolvedSimpleValueArray = simpleValueArray; + if (macros != null && !macros.isEmpty()) { + for (int i = 0; i < resolvedSimpleValueArray.length; i++) { + resolvedSimpleValueArray[i] = ProcessHelper.getValueAfterExpandingMacros(resolvedSimpleValueArray[i], macros, valueStore); + } + } + break; + case ProcessParameter.COMPLEX: + for(int i=0; i<complexValue.length; i++) { + ProcessArgument arg = complexValue[i]; + arg.resolve(); + } + break; + case ProcessParameter.COMPLEX_ARRAY: + for(int i=0; i<complexValueArray.length; i++) { + ProcessArgument[] complexValue =complexValueArray[i]; + for(int j=0; j<complexValue.length; j++) { + ProcessArgument arg = complexValue[j]; + arg.resolve(); + } + } + break; + } + resolved = true; + } + + /** + * Checks whether the process argument has resolved. + * @return boolean, true if resolved. + */ + public boolean isResolved() { + return resolved; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer b = new StringBuffer(name); + b.append(":"); //$NON-NLS-1$ + switch (type) { + case ProcessParameter.SIMPLE: + return b.append(getSimpleValue()).toString(); + case ProcessParameter.SIMPLE_ARRAY: + b.append("{"); //$NON-NLS-1$ + String[] strings = getSimpleArrayValue(); + for(int i=0; i<strings.length; i++) { + b.append(strings[i]).append(", "); //$NON-NLS-1$ + } + if (b.charAt(b.length() - 1) == ' ') { + b.replace(b.length() - 2, b.length(), "}"); //$NON-NLS-1$ + } else { + b.append("}"); //$NON-NLS-1$ + } + return b.toString(); + case ProcessParameter.COMPLEX: + b.append("{"); //$NON-NLS-1$ + ProcessArgument[] args = getComplexValue(); + for(int i=0; i<args.length; i++) { + ProcessArgument arg = args[i]; + b.append(arg).append(", "); //$NON-NLS-1$ + } + if (b.charAt(b.length() - 1) == ' ') { + b.replace(b.length() - 2, b.length(), "}"); //$NON-NLS-1$ + } else { + b.append("}"); //$NON-NLS-1$ + } + return b.toString(); + case ProcessParameter.COMPLEX_ARRAY: + b.append("{"); //$NON-NLS-1$ + ProcessArgument[][] argssCA = getComplexArrayValue(); + for(int i=0; i<argssCA.length; i++) { + ProcessArgument[] argsCA = argssCA[i]; + b.append("{"); //$NON-NLS-1$ + for(int j=0; j<argsCA.length; j++) { + ProcessArgument arg = argsCA[j]; + b.append(arg).append(", "); //$NON-NLS-1$ + } + if (b.charAt(b.length() - 1) == ' ') { + b.replace(b.length() - 2, b.length(), "}, "); //$NON-NLS-1$ + } else { + b.append("}, "); //$NON-NLS-1$ + } + } + if (b.charAt(b.length() - 1) == ' ') { + b.replace(b.length() - 2, b.length(), "}"); //$NON-NLS-1$ + } else { + b.append("}"); //$NON-NLS-1$ + } + return b.toString(); + } + return ""; //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessFailureException.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessFailureException.java new file mode 100644 index 00000000000..4c874d9e6e9 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessFailureException.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import java.util.List; + +public class ProcessFailureException extends Exception { + private static final long serialVersionUID = 1766239661286962870L; + private List/*<IStatus>*/ statuses; + + /** + * Constructor based on the msg. + * @param msg + */ + public ProcessFailureException(String msg) { + super(msg); + } + + /** + * Constructor based on the msg and cause. + * @param cause + */ + public ProcessFailureException(Throwable cause) { + super(cause); + } + + /** + * Constructor based on the msg and cause. + * @param msg + * @param cause + */ + public ProcessFailureException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * Constructor based on the msg and causes. + * @param msg + * @param statuses + */ + public ProcessFailureException(String msg, List/*<IStatus>*/ statuses) { + super(msg); + this.statuses = statuses; + } + + public ProcessFailureException(String msg, Throwable cause, List/*<IStatus>*/ statuses) { + super(msg, cause); + this.statuses = statuses; + } + + /** + * Returns the Statuses. + * @return List, contains the IStatus. + */ + public List/*<IStatus>*/ getStatuses() { + return statuses; + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessHelper.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessHelper.java new file mode 100644 index 00000000000..d8d7f0d14ea --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessHelper.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.RandomAccessFile; +import java.net.URL; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.templateengine.TemplateEngineMessages; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; + +/** + * Acts as Helper class for process the processes i.e., copy, replace and append + * files. + */ +public class ProcessHelper { + public static final String CONDITION = "condition"; //$NON-NLS-1$ + public static final String START_PATTERN = "$("; //$NON-NLS-1$ + public static final String END_PATTERN = ")"; //$NON-NLS-1$ + public static final String EQUALS = "=="; //$NON-NLS-1$ + public static final String NOT_EQUALS = "!="; //$NON-NLS-1$ + + /** + * This method is to append the given contents into a file. + * + * @param fileContents, + * contents which are appended to the file. + * @param toFile, + * a file to append contents. + * @throws IOException, + * exception while writing contents into a file + * + * @since 4.0 + */ + public static void appendFile(String fileContents, File toFile) throws IOException { + RandomAccessFile raf = null; + if (!toFile.exists()) { + throw new FileNotFoundException(" The specified destination file does not exists "); //$NON-NLS-1$ + } else { + try { + raf = new RandomAccessFile(toFile, "rw"); //$NON-NLS-1$ + raf.skipBytes((int) raf.length()); + raf.writeBytes(fileContents); + } finally { + raf.close(); + } + } + } + + /** + * This method returns a vector of all replace marker strings. (e.g., + * $(item), vector contains 'item' as one item. , ) is the end pattern. + * + * @param str, + * A given string may contains replace markers. + * @param pattern + * start pattern (e.g., $( is the start pattern) + * @param endPat + * end pattern (e.g., ) is the end pattern) + * @return a set of all replace marker strings. + * + * @since 4.0 + */ + public static Set/*<String>*/ getReplaceKeys(String str) { + int start = 0; + int end = 0; + Set/*<String>*/ replaceStrings = new HashSet/*<String>*/(); + while ((start = str.indexOf(START_PATTERN, start)) >= 0) { + end = str.indexOf(END_PATTERN, start); + if (end != -1) { + replaceStrings.add(str.substring(start + START_PATTERN.length(), end)); + start = end + START_PATTERN.length(); + } else + start++; + } + return replaceStrings; + } + + /** + * This method takes a URL as parameter to read the contents, and to add + * into a string buffer. + * + * @param source + * URL to read the contents. + * @return string, contents of a file specified in the URL source path. + * @throws IOException + * + * @since 4.0 + */ + public static String readFromFile(URL source) throws IOException { + char[] chars = new char[4092]; + InputStreamReader contentsReader = null; + StringBuffer buffer = new StringBuffer(); + if (!new java.io.File(source.getFile()).exists()) { + throw new FileNotFoundException(TemplateEngineMessages.getString("ProcessHelper.fileNotFound") + source.getFile()); //$NON-NLS-1$ + } else { + contentsReader = new InputStreamReader(source.openStream()); + int c; + do { + c = contentsReader.read(chars); + if (c == -1) + break; + buffer.append(chars, 0, c); + } while (c != -1); + contentsReader.close(); + } + return buffer.toString(); + } + + /** + * This method reads contents from source, and writes the contents into + * destination file. + * + * @param source + * URL to read the contents. + * @param dest + * destination file to write the contents. + * @throws IOException + * + * @since 4.0 + */ + public static void copyBinaryFile(URL source, File dest) throws IOException { + byte[] bytes = new byte[4092]; + if (source != null && dest != null) { + File file = new File(source.getFile()); + if (file.isFile()) { + FileInputStream fis = new FileInputStream(file); + FileOutputStream fos = new FileOutputStream(dest); + int ch; + while (true) { + ch = fis.read(bytes); + if (ch == -1) { + break; + } + fos.write(bytes, 0, ch); + } + } + } + } + + /** + * This method Creates the Directories in the parent Folder. + * @param projectHandle + * @param parentFolder + * @throws CoreException + * + * @since 4.0 + */ + public static void mkdirs(IProject projectHandle, IFolder parentFolder) throws CoreException { + if (parentFolder.getProjectRelativePath().equals(projectHandle.getProjectRelativePath())) { + return; + } + if (!parentFolder.getParent().exists()) { + mkdirs(projectHandle, projectHandle.getFolder(parentFolder.getParent().getProjectRelativePath())); + } + parentFolder.create(true, true, null); + } + + + /** + * Returns the Macro Value after Exanding the Macros. + * @param string + * @param macros + * @param valueStore + * @return + * + * @since 4.0 + */ + public static String getValueAfterExpandingMacros(String string, Set/*<String>*/ macros, Map/*<String, String>*/ valueStore) { + for (Iterator i = macros.iterator(); i.hasNext();) { + String key = (String) i.next(); + String value = (String) valueStore.get(key); + if (value != null) { + string = replace(START_PATTERN + key + END_PATTERN, value, string); + } + } + return string; + } + + /** + * This is equivalent to Java 5.0 version of + * String.replace(CharSequence target, CharSequence replacement) method. + * @since 4.0 + */ + private static String replace(String target, String replacement, String string) { + try { + StringBuffer stringBuffer = new StringBuffer(string); + + int index = string.length(); + int offset = target.length(); + + while ((index=string.lastIndexOf(target, index-1)) != -1) { + stringBuffer.replace(index, index+offset, replacement); + } + + return stringBuffer.toString(); + } catch (StringIndexOutOfBoundsException e) { + return string; + } + } + + /** + * Consturct and Return the Replacment Markers + * after adding the patterns to the macro. + * @param macro + * @return + * + * @since 4.0 + */ + public static String getReplaceMarker(String macro) { + return START_PATTERN + macro + END_PATTERN; + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessParameter.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessParameter.java new file mode 100644 index 00000000000..ce43a2bedd0 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessParameter.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * ProcessParameter is responsible for construting the Process Parameter the given configuration element. + */ +public class ProcessParameter { + public static final byte SIMPLE = 1; + public static final byte SIMPLE_ARRAY = 2; + public static final byte COMPLEX = 3; + public static final byte COMPLEX_ARRAY = 4; + + private static final String ELEM_NAME = "name"; //$NON-NLS-1$ + private static final String ELEM_BASE_TYPE = "baseType"; //$NON-NLS-1$ + private static final String ELEM_SIMPLE = "simple"; //$NON-NLS-1$ + private static final String ELEM_SIMPLE_ARRAY = "simpleArray"; //$NON-NLS-1$ + private static final String ELEM_COMPLEX = "complex"; //$NON-NLS-1$ + private static final String ELEM_COMPLEX_ARRAY = "complexArray"; //$NON-NLS-1$ + private static final String ELEM_EXTERNAL = "external"; //$NON-NLS-1$ + private static final String ELEM_NULLABLE = "nullable"; //$NON-NLS-1$ + + private String name; + private byte type; + + private ProcessParameter[] complexChildren; + private boolean external; + private boolean nullable; + + /** + * Constructor to extract the parameter info. + * @param element + */ + public ProcessParameter(IConfigurationElement element) { + this.name = element.getAttribute(ELEM_NAME); + String elemName = element.getName(); + if (elemName.equals(ELEM_SIMPLE)) { + type = SIMPLE; + } else if (elemName.equals(ELEM_SIMPLE_ARRAY)) { + type = SIMPLE_ARRAY; + } else if (elemName.equals(ELEM_COMPLEX)) { + type = COMPLEX; + IConfigurationElement[] children = element.getChildren(); + complexChildren = new ProcessParameter[children.length]; + for(int i=0; i<children.length; i++) { + complexChildren[i] = new ProcessParameter(children[i]); + } + } else if (elemName.equals(ELEM_COMPLEX_ARRAY)) { + type = COMPLEX_ARRAY; + IConfigurationElement baseType = element.getChildren(ELEM_BASE_TYPE)[0]; + IConfigurationElement[] children = baseType.getChildren(); + complexChildren = new ProcessParameter[children.length]; + for(int i=0; i<children.length; i++) { + complexChildren[i] = new ProcessParameter(children[i]); + } + } else { + throw new IllegalArgumentException(); + } + + external = Boolean.valueOf(element.getAttribute(ELEM_EXTERNAL)).booleanValue(); + nullable = Boolean.valueOf(element.getAttribute(ELEM_NULLABLE)).booleanValue(); + } + + /** + * Return the Element name. + * @return + */ + public String getName() { + return name; + } + + /** + * Returns the Element Type. + * @return + */ + public byte getType() { + return type; + } + + /** + * @return the complexChildren + */ + public ProcessParameter[] getComplexChildren() { + return complexChildren; + } + + /** + * Checks whether the element in external. + * @return + */ + public boolean isExternal() { + return external; + } + + /** + * @return the nullable + */ + public boolean isNullable() { + return nullable; + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessRunner.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessRunner.java new file mode 100644 index 00000000000..47c9cd9a726 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessRunner.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateEngineMessages; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + + +/** + * Abstract ProcessRunner class provides the methods to implement for processes. + */ +public abstract class ProcessRunner { + + private ProcessParameter[] params; + + void setProcessParameters(ProcessParameter[] params) { + this.params = params; + } + + /** + * Returns the Process Parameters. + * @return + */ + public ProcessParameter[] getProcessParameters() { + return params; + } + + /** + * Checks the whether the arguments are matching to Requied Parameters. + * @param args + * @return + */ + protected final boolean areArgumentsMatchingRequiredParameters(ProcessArgument[] args) { + if ((params == null && args != null) || (params != null && args == null)) { + return false; + } + if (params == null && args == null) { + return true; + } + if (params.length != args.length) { + return false; + } + for (int i = 0; i < params.length; i++) { + if (!args[i].isOfParameterType(params[i])) { + return false; + } + } + return true; + } + + /** + * Return the String containing the mismatching message + * if the arguments are not matching to Requied Parameters. + * @param args + * @return + */ + public String getArgumentsMismatchMessage(ProcessArgument[] args) { + if (params == null && args != null) { + return TemplateEngineMessages.getString("ProcessRunner.unexpectedArguments"); //$NON-NLS-1$ + } + if (params != null && args == null) { + return TemplateEngineMessages.getString("ProcessRunner.missingArguments"); //$NON-NLS-1$ + } + if (params == null && args == null) { + return null; + } + if (params.length != args.length) { + return TemplateEngineMessages.getString("ProcessRunner.missingArguments"); //$NON-NLS-1$ + } + for (int i = 0; i < params.length; i++) { + ProcessParameter param = params[i]; + ProcessArgument arg = args[i]; + if (!arg.isOfParameterType(param)) { + return TemplateEngineMessages.getString("ProcessRunner.argumentsMismatch") + arg.getName(); //$NON-NLS-1$ + } + } + return null; + } + + /** + * Returns the process message based on the pameters. + * @param processId + * @param code + * @param msg + * @return + */ + protected final String getProcessMessage(String processId, int code, String msg) { + switch (code) { + case IStatus.ERROR: + return processId + TemplateEngineMessages.getString("ProcessRunner.error") + msg; //$NON-NLS-1$ + case IStatus.OK: + return processId + TemplateEngineMessages.getString("ProcessRunner.success") + msg; //$NON-NLS-1$ + default: + return processId + TemplateEngineMessages.getString("ProcessRunner.info") + msg; //$NON-NLS-1$ + } + } + + /** + * @param template + * @param args + * @param processId + * @throws ProcessFailureException + */ + public abstract void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException; +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessRunnerFactory.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessRunnerFactory.java new file mode 100644 index 00000000000..fa9c2f4a62d --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/ProcessRunnerFactory.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.templateengine.TemplateEngineUtil; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; + + +/** + * Factory class for creating the Process Runners. + */ +public class ProcessRunnerFactory { + private static final String EXTENSION_POINT_PROCESSES = CCorePlugin.PLUGIN_ID + ".templateProcessTypes"; //$NON-NLS-1$ + private static final String ELEM_NAME = "name"; //$NON-NLS-1$ + private static final String ELEM_PROCESS_RUNNER = "processRunner"; //$NON-NLS-1$ + private static ProcessRunnerFactory instance; + + static { + instance = new ProcessRunnerFactory(); + } + + private Map/*<String, ProcessRunner>*/ processRunnerMap; + + private ProcessRunnerFactory() { + initializeProcessRunners(); + } + + /** + * initializes the process runners. + * + */ + private synchronized void initializeProcessRunners() { + processRunnerMap = new HashMap/*<String, ProcessRunner>*/(); + IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(EXTENSION_POINT_PROCESSES); + IExtension[] extensions = point.getExtensions(); + for(int i=0; i<extensions.length; i++) { + IExtension extension = extensions[i]; + String prefix = extension.getNamespaceIdentifier() + "."; //$NON-NLS-1$ + IConfigurationElement[] configurationElements = extension.getConfigurationElements(); + for(int j=0; j<configurationElements.length; j++) { + IConfigurationElement element = configurationElements[j]; + String processType = element.getAttribute(ELEM_NAME); + if (processType != null) { + try { + ProcessRunner runner = (ProcessRunner) element.createExecutableExtension(ELEM_PROCESS_RUNNER); + List/*<ProcessParameter>*/ params = null; + IConfigurationElement[] elementChildren = element.getChildren(); + for (int k=0; k<elementChildren.length; k++) { + if (params == null) { + params = new ArrayList/*<ProcessParameter>*/(); + } + params.add(new ProcessParameter(elementChildren[k])); + } + if (params != null) { + runner.setProcessParameters((ProcessParameter[])params.toArray(new ProcessParameter[params.size()])); + } + processRunnerMap.put(prefix + processType, runner); + } catch (CoreException e) { + TemplateEngineUtil.log(e); +// TemplateEngine.showError(e.getMessage(), e); + } + } + } + } + } + + /** + * Process Runners Factory instace. + * @return + */ + public static ProcessRunnerFactory getDefault() { + return instance; + } + + /** + * Return the ProcessRunner based on the ProcessType. + * @param processType + * @return + */ + public ProcessRunner getProcessRunner(String processType) { + return (ProcessRunner) processRunnerMap.get(processType); + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/TemplateProcessHandler.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/TemplateProcessHandler.java new file mode 100644 index 00000000000..eab75afe3ca --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/TemplateProcessHandler.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateDescriptor; +import org.eclipse.cdt.core.templateengine.TemplateEngine; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.w3c.dom.Element; + + +/** + * Class handles the Template processes + */ +public class TemplateProcessHandler { + + private TemplateCore template; + private List/*<ConditionalProcessGroup>*/ conditionalProcessGroupList; + + public TemplateProcessHandler(TemplateCore template) { + this.template = template; + initialize(); + } + + /** + * initializes the template descriptor and Root Elements. + * + */ + private void initialize() { + TemplateDescriptor desc = template.getTemplateDescriptor(); + Element root = desc.getRootElement(); + conditionalProcessGroupList = new ArrayList/*<ConditionalProcessGroup>*/(); + List/*<Element>*/ nodeList = TemplateEngine.getChildrenOfElementByTag(root, TemplateDescriptor.IF); + for (int j = 0, l = nodeList.size(); j < l; j++) { + conditionalProcessGroupList.add(new ConditionalProcessGroup(template, (Element) nodeList.get(j), j + 1)); + } + //Collect all free-hanging processes in one ConditionalProcessGroup object with condition true. + nodeList = TemplateEngine.getChildrenOfElementByTag(root, TemplateDescriptor.PROCESS); + conditionalProcessGroupList.add(new ConditionalProcessGroup(template, (Element[]) nodeList.toArray(new Element[nodeList.size()]))); + } + + /** + * + * @param monitor + * @return IStatus, as an array of status info + * @throws ProcessFailureException + */ + public IStatus[] processAll(IProgressMonitor monitor) throws ProcessFailureException { + List/*<IStatus>*/ allStatuses = new ArrayList/*<IStatus>*/(); + for (Iterator i = conditionalProcessGroupList.iterator(); i.hasNext();) { + try { + allStatuses.addAll(((ConditionalProcessGroup)i.next()).process(monitor)); + } catch (ProcessFailureException e) { + throw new ProcessFailureException(e.getMessage(), e, allStatuses); + } + } + return (IStatus[]) allStatuses.toArray(new IStatus[allStatuses.size()]); + } + + /** + * Returns all macros + * @return + */ + public Set/*<String>*/ getAllMacros() { + Set/*<String>*/ set = null; + for (Iterator i = conditionalProcessGroupList.iterator(); i.hasNext();) { + Set/*<String>*/ subSet = ((ConditionalProcessGroup)i.next()).getAllMacros(); + if (subSet != null) { + if (set == null) { + set = new HashSet/*<String>*/(); + } + set.addAll(subSet); + } + } + return set; + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddFile.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddFile.java new file mode 100644 index 00000000000..245867027bf --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddFile.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateEngineHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessArgument; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.ProcessHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessRunner; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + + +/** + * Adds File to the project + */ +public class AddFile extends ProcessRunner { + + /** + * This method Adds the File to the corresponding Project. + */ + public void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException { + String projectName = args[0].getSimpleValue(); + ProcessArgument file = args[1]; + ProcessArgument[] fileMembers = file.getComplexValue(); + String fileSourcePath = fileMembers[0].getSimpleValue(); + String fileTargetPath = fileMembers[1].getSimpleValue(); + boolean replaceable = fileMembers[2].getSimpleValue().equals("true"); //$NON-NLS-1$ + + IProject projectHandle = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + URL path; + try { + path = TemplateEngineHelper.getTemplateResourceURLRelativeToTemplate(template, fileSourcePath); + if (path == null) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("AddFile.0") + fileSourcePath)); //$NON-NLS-1$ + } + } catch (IOException e1) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("AddFile.1") + fileSourcePath)); //$NON-NLS-1$ + } + + InputStream contents = null; + if (replaceable) { + String fileContents; + try { + fileContents = ProcessHelper.readFromFile(path); + } catch (IOException e) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("AddFile.2") + fileSourcePath)); //$NON-NLS-1$ + } + fileContents = ProcessHelper.getValueAfterExpandingMacros(fileContents, ProcessHelper.getReplaceKeys(fileContents), template.getValueStore()); + contents = new ByteArrayInputStream(fileContents.getBytes()); + } else { + try { + contents = path.openStream(); + } catch (IOException e) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("AddFile.3") + fileSourcePath)); //$NON-NLS-1$ + } + } + + try { + IFile iFile = projectHandle.getFile(fileTargetPath); + if (!iFile.getParent().exists()) { + ProcessHelper.mkdirs(projectHandle, projectHandle.getFolder(iFile.getParent().getProjectRelativePath())); + } + iFile.create(contents, true, null); + iFile.refreshLocal(IResource.DEPTH_ONE, null); + projectHandle.refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("AddFile.4") + e.getMessage()), e); //$NON-NLS-1$ + } + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddFiles.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddFiles.java new file mode 100644 index 00000000000..bd11bf60268 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddFiles.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateEngineHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessArgument; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.ProcessHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessRunner; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + + +/** + * Adds Files to the Project + */ +public class AddFiles extends ProcessRunner { + + /** + * This method Adds the list of Files to the corresponding Project. + */ + public void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException { + String projectName = args[0].getSimpleValue(); + IProject projectHandle = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + ProcessArgument[][] files = args[1].getComplexArrayValue(); + for(int i=0; i<files.length; i++) { + ProcessArgument[] file = files[i]; + String fileSourcePath = file[0].getSimpleValue(); + String fileTargetPath = file[1].getSimpleValue(); + boolean replaceable = file[2].getSimpleValue().equals("true"); //$NON-NLS-1$ + + URL path; + try { + path = TemplateEngineHelper.getTemplateResourceURLRelativeToTemplate(template, fileSourcePath); + if (path == null) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("AddFiles.1") + fileSourcePath)); //$NON-NLS-1$ + } + } catch (IOException e1) { + throw new ProcessFailureException(Messages.getString("AddFiles.2") + fileSourcePath); //$NON-NLS-1$ + } + + InputStream contents = null; + if (replaceable) { + String fileContents; + try { + fileContents = ProcessHelper.readFromFile(path); + } catch (IOException e) { + throw new ProcessFailureException(Messages.getString("AddFiles.3") + fileSourcePath); //$NON-NLS-1$ + } + fileContents = ProcessHelper.getValueAfterExpandingMacros(fileContents, ProcessHelper.getReplaceKeys(fileContents), template.getValueStore()); + contents = new ByteArrayInputStream(fileContents.getBytes()); + } else { + try { + contents = path.openStream(); + } catch (IOException e) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("AddFiles.4") + fileSourcePath)); //$NON-NLS-1$ + } + } + + try { + IFile iFile = projectHandle.getFile(fileTargetPath); + if (!iFile.getParent().exists()) { + ProcessHelper.mkdirs(projectHandle, projectHandle.getFolder(iFile.getParent().getProjectRelativePath())); + } + + if (iFile.exists()) { + // honor the replaceable flag and replace the file contents if the file already exists. + if (replaceable) { + iFile.setContents(contents, true, true, null); + } else { + throw new ProcessFailureException(Messages.getString("AddFiles.5")); //$NON-NLS-1$ + } + + } else { + iFile.create(contents, true, null); + iFile.refreshLocal(IResource.DEPTH_ONE, null); + } + } catch (CoreException e) { + throw new ProcessFailureException(Messages.getString("AddFiles.6") + e.getMessage(), e); //$NON-NLS-1$ + } + } + try { + projectHandle.refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + throw new ProcessFailureException(Messages.getString("AddFiles.7") + e.getMessage(), e); //$NON-NLS-1$ + } + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddLink.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddLink.java new file mode 100644 index 00000000000..930bfe65455 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AddLink.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import java.io.File; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.process.ProcessArgument; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.ProcessHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessRunner; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; + + +/** + * Adds a Link to the Project. + */ +public class AddLink extends ProcessRunner { + + /** + * This method Adds a Link to the Project. + */ + public void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException { + String projectName = args[0].getSimpleValue(); + String fileSourcePath = args[1].getSimpleValue(); + String targetPath = args[2].getSimpleValue(); + + File sourceFile = new java.io.File(fileSourcePath); + + IProject projectHandle = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + + try { + IFile file = projectHandle.getFile(targetPath); + if (!file.getParent().exists()) { + ProcessHelper.mkdirs(projectHandle, projectHandle.getFolder(file.getParent().getProjectRelativePath())); + } + file.createLink(Path.fromOSString(sourceFile.getAbsolutePath()), IResource.ALLOW_MISSING_LOCAL | IResource.BACKGROUND_REFRESH, null); + file.refreshLocal(IResource.DEPTH_ONE, null); + projectHandle.refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + throw new ProcessFailureException(Messages.getString("AddLink.0") + e.getMessage(), e); //$NON-NLS-1$ + } + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Append.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Append.java new file mode 100644 index 00000000000..5577b702a20 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Append.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateEngineHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessArgument; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.ProcessHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessRunner; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + + +/** + * Append the contents to the file. + */ +public class Append extends ProcessRunner { + + /** + * This method Appends the contents to a file. + */ + public void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException { + ProcessArgument[][] files = args[0].getComplexArrayValue(); + for(int i=0; i<files.length; i++) { + ProcessArgument[] file = files[i]; + String sourcePath = file[0].getSimpleValue(); + URL sourceURL; + try { + sourceURL = TemplateEngineHelper.getTemplateResourceURLRelativeToTemplate(template, sourcePath); + if (sourceURL == null) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("Append.0") + sourcePath)); //$NON-NLS-1$ + } + } catch (IOException e1) { + throw new ProcessFailureException(Messages.getString("Append.1") + sourcePath); //$NON-NLS-1$ + } + File targetFile = new File(file[1].getSimpleValue()); + boolean replaceable = file[2].getSimpleValue().equals("true"); //$NON-NLS-1$ + String fileContents; + try { + fileContents = ProcessHelper.readFromFile(sourceURL); + } catch (IOException e1) { + throw new ProcessFailureException(Messages.getString("Append.3") + sourcePath); //$NON-NLS-1$ + } + if (replaceable) { + fileContents = ProcessHelper.getValueAfterExpandingMacros(fileContents, ProcessHelper.getReplaceKeys(fileContents), template.getValueStore()); + } + try { + ProcessHelper.appendFile(fileContents, targetFile); + } catch (IOException e) { + throw new ProcessFailureException(Messages.getString("Append.4"), e); //$NON-NLS-1$ + } + } + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AppendCreate.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AppendCreate.java new file mode 100644 index 00000000000..63e49f1e950 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/AppendCreate.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateEngineHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessArgument; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.ProcessHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessRunner; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + + +/* + * Appends a file to an existing file if present. If not, create the file + */ +public class AppendCreate extends ProcessRunner { + public void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException { + String projectName = args[0].getSimpleValue(); + IProject projectHandle = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + ProcessArgument[][] files = args[1].getComplexArrayValue(); + for(int i=0; i<files.length; i++) { + ProcessArgument[] file = files[i]; + String sourcePath = file[0].getSimpleValue(); + String targetPath = file[1].getSimpleValue(); + boolean replaceable = file[2].getSimpleValue().equals("true"); //$NON-NLS-1$ + + URL sourceURL; + try { + sourceURL = TemplateEngineHelper.getTemplateResourceURLRelativeToTemplate(template, sourcePath); + if (sourceURL == null) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("AppendCreate.1") + sourcePath)); //$NON-NLS-1$ + } + } catch (IOException e1) { + throw new ProcessFailureException(Messages.getString("AppendCreate.2") + sourcePath); //$NON-NLS-1$ + } + String fileContents; + try { + fileContents = ProcessHelper.readFromFile(sourceURL); + } catch (IOException e1) { + throw new ProcessFailureException(Messages.getString("AppendCreate.3") + sourcePath); //$NON-NLS-1$ + } + if (replaceable) { + fileContents = ProcessHelper.getValueAfterExpandingMacros(fileContents, ProcessHelper.getReplaceKeys(fileContents), template.getValueStore()); + } + try { + // Check whether the file exists + IFile iFile = projectHandle.getFile(targetPath); + if (!iFile.getParent().exists()) { + ProcessHelper.mkdirs(projectHandle, projectHandle.getFolder(iFile.getParent().getProjectRelativePath())); + } + InputStream contents = new ByteArrayInputStream(fileContents.getBytes());; + if (!iFile.exists()) { + // Create the file + iFile.create(contents, true, null); + iFile.refreshLocal(IResource.DEPTH_ONE, null); + + } else { + // Append the file keeping the history + iFile.appendContents(contents, true, true, null); + } + // Update the project + projectHandle.refreshLocal(IResource.DEPTH_INFINITE, null); + + } catch (CoreException e) { + throw new ProcessFailureException(Messages.getString("AppendCreate.4"), e); //$NON-NLS-1$ + } + } + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Copy.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Copy.java new file mode 100644 index 00000000000..be02c089a9e --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Copy.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URL; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.TemplateEngineHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessArgument; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.ProcessHelper; +import org.eclipse.cdt.core.templateengine.process.ProcessRunner; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + + +/** + * Copies a File to the Project. + */ +public class Copy extends ProcessRunner { + + /** + * This method Copies a File to the Project. + */ + public void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException { + ProcessArgument[][] files = args[0].getComplexArrayValue(); + for(int i=0; i<files.length; i++) { + ProcessArgument[] file = files[i]; + String sourcePath = file[0].getSimpleValue(); + URL sourceURL; + try { + sourceURL = TemplateEngineHelper.getTemplateResourceURLRelativeToTemplate(template, sourcePath); + if (sourceURL == null) { + throw new ProcessFailureException(getProcessMessage(processId, IStatus.ERROR, Messages.getString("Copy.0") + sourcePath)); //$NON-NLS-1$ + } + } catch (IOException e1) { + throw new ProcessFailureException(Messages.getString("Copy.1") + sourcePath); //$NON-NLS-1$ + } + File targetFile = new File(file[1].getSimpleValue()); + boolean replaceable = file[2].getSimpleValue().equals("true"); //$NON-NLS-1$ + if (replaceable) { + String fileContents; + try { + fileContents = ProcessHelper.readFromFile(sourceURL); + } catch (IOException e1) { + throw new ProcessFailureException(Messages.getString("Copy.3") + sourcePath); //$NON-NLS-1$ + } + fileContents = ProcessHelper.getValueAfterExpandingMacros(fileContents, ProcessHelper.getReplaceKeys(fileContents), template.getValueStore()); + if (!targetFile.getParentFile().exists()) { + targetFile.getParentFile().mkdirs(); + } + FileWriter writer = null; + try { + writer = new FileWriter(targetFile); + writer.write(fileContents); + } catch (IOException e) { + throw new ProcessFailureException(Messages.getString("Copy.4"), e); //$NON-NLS-1$ + } finally { + if (writer != null) { + try { + writer.close(); + } catch (IOException ioe) {// ignore + } + } + } + } else { + try { + ProcessHelper.copyBinaryFile(sourceURL, targetFile); + } catch (IOException e) { + throw new ProcessFailureException(Messages.getString("Copy.5"), e); //$NON-NLS-1$ + } + } + } + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/CreateResourceIdentifier.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/CreateResourceIdentifier.java new file mode 100644 index 00000000000..65046b58576 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/CreateResourceIdentifier.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.process.ProcessArgument; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.ProcessRunner; +import org.eclipse.core.runtime.IProgressMonitor; + + +/** + * Creates a template macro value that can be used as a pseudo-unique resource identifier. + * It is based on the name of the application and is in the form of four capital letters. + * e.g. Helloworld => HELL + */ +public class CreateResourceIdentifier extends ProcessRunner { + + public void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException { + String valueName = args[0].getSimpleValue(); + String appName = args[1].getSimpleValue(); + + String value = ""; //$NON-NLS-1$ + if (appName.length() >= 4) { + value = appName.substring(0, 4).toUpperCase(); + } else { + value = appName.toUpperCase(); + for (int i=0; i<4-appName.length(); i++) { + value = value + "X"; //$NON-NLS-1$ + } + } + template.getValueStore().put(valueName, value); + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/CreateSourceFolder.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/CreateSourceFolder.java new file mode 100644 index 00000000000..bda5d6b94b6 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/CreateSourceFolder.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.core.settings.model.CSourceEntry; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.core.settings.model.ICSourceEntry; +import org.eclipse.cdt.core.settings.model.WriteAccessException; +import org.eclipse.cdt.core.templateengine.TemplateCore; +import org.eclipse.cdt.core.templateengine.process.ProcessArgument; +import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; +import org.eclipse.cdt.core.templateengine.process.ProcessRunner; +import org.eclipse.core.resources.IFolder; +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; + + +/** + * Creates a include Folder to the project. + */ +public class CreateSourceFolder extends ProcessRunner { + + public void process(TemplateCore template, ProcessArgument[] args, String processId, IProgressMonitor monitor) throws ProcessFailureException { + createSourceFolder(args[0].getSimpleValue(), args[1].getSimpleValue(), monitor); + } + + protected void createSourceFolder(String projectName, String targetPath, IProgressMonitor monitor) throws ProcessFailureException { + IProject projectHandle = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + + if (!projectHandle.exists()) { + throw new ProcessFailureException(Messages.getString("CreateSourceFolder.0") + projectName); //$NON-NLS-1$ + } + + IPath projPath = projectHandle.getFullPath(); + + IFolder folder = projectHandle.getFolder(targetPath); + if (!folder.exists()) { + try { + folder.create(true, true, monitor); + } catch (CoreException e) { + throw new ProcessFailureException(Messages.getString("CreateSourceFolder.1") + e.getMessage(), e); //$NON-NLS-1$ + } + } + + try { + ICProject cProject = CoreModel.getDefault().create(projectHandle); + if (cProject != null) { + if(CCorePlugin.getDefault().isNewStyleProject(cProject.getProject())){ + //create source folder for new style project + createNewStyleProjectFolder(monitor, projectHandle, folder); + } else { + //create source folder for all other projects + createFolder(targetPath, monitor, projPath, cProject); + } + } + } catch (WriteAccessException e) { + throw new ProcessFailureException(Messages.getString("CreateSourceFolder.2") + e.getMessage(), e); //$NON-NLS-1$ + } catch (CoreException e) { + throw new ProcessFailureException(Messages.getString("CreateSourceFolder.2") + e.getMessage(), e); //$NON-NLS-1$ + } + } + + /** + * @param monitor + * @param projectHandle + * @param folder + * @throws CoreException + * @throws WriteAccessException + */ + private void createNewStyleProjectFolder(IProgressMonitor monitor, IProject projectHandle, IFolder folder) throws CoreException, WriteAccessException { + ICSourceEntry newEntry = new CSourceEntry(folder, null, 0); + ICProjectDescription description = CCorePlugin.getDefault().getProjectDescription(projectHandle); + + ICConfigurationDescription configs[] = description.getConfigurations(); + for(int i=0; i < configs.length; i++){ + ICConfigurationDescription config = configs[i]; + ICSourceEntry[] entries = config.getSourceEntries(); + Set set = new HashSet(); + for (int j=0; j < entries.length; j++) { + set.add(entries[j]); + } + set.add(newEntry); + config.setSourceEntries((ICSourceEntry[])set.toArray(new ICSourceEntry[set.size()])); + } + + CCorePlugin.getDefault().setProjectDescription(projectHandle, description, false, monitor); + } + + /** + * @param targetPath + * @param monitor + * @param projPath + * @param cProject + * @throws CModelException + */ + private void createFolder(String targetPath, IProgressMonitor monitor, IPath projPath, ICProject cProject) throws CModelException { + IPathEntry[] entries = cProject.getRawPathEntries(); + List/*<IPathEntry>*/ newEntries = new ArrayList/*<IPathEntry>*/(entries.length + 1); + + int projectEntryIndex= -1; + IPath path = projPath.append(targetPath); + + for (int i = 0; i < entries.length; i++) { + IPathEntry curr = entries[i]; + if (path.equals(curr.getPath())) { + // just return if this folder exists already + return; + } + if (projPath.equals(curr.getPath())) { + projectEntryIndex = i; + } + newEntries.add(curr); + } + + IPathEntry newEntry = CoreModel.newSourceEntry(path); + + if (projectEntryIndex != -1) { + newEntries.set(projectEntryIndex, newEntry); + } else { + newEntries.add(CoreModel.newSourceEntry(path)); + } + + cProject.setRawPathEntries((IPathEntry[])newEntries.toArray(new IPathEntry[newEntries.size()]), monitor); + } + +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Messages.java b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Messages.java new file mode 100644 index 00000000000..863aaef9f1b --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/Messages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Limited 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: + * Bala Torati (Symbian) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.templateengine.process.processes; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages { + private static final String BUNDLE_NAME = "org.eclipse.cdt.core.templateengine.process.processes.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private Messages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/messages.properties b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/messages.properties new file mode 100644 index 00000000000..833b13cab31 --- /dev/null +++ b/core/org.eclipse.cdt.core/templateengine/org/eclipse/cdt/core/templateengine/process/processes/messages.properties @@ -0,0 +1,58 @@ +############################################################################### +# Copyright (c) 2007 Symbian Software Limited 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: +# Bala Torati (Symbian) - Initial API and implementation +############################################################################### + +AddFiles.1=Add File failure: template source not found: +AddFiles.2=Add Files failure: template source not found: +AddFiles.3=Add Files failure: cannot read template source: +AddFiles.4=Add File failure: cannot read template source: +AddFiles.5=Add Files failure: File already exists. +AddFiles.6=Add Files failure: +AddFiles.7=Add Files failure: +AddFile.0=Add File failure: template source not found: +AddFile.1=Add File failure: template source not found: +AddFile.2=Add File failure: cannot read template source: +AddFile.3=Add File failure: cannot read template source: +AddFile.4=Add File failure: +AddLink.0=Add Link failure: +SetMBSBooleanOptionValue.0=SetMBSBooleanOptionValue failure: +SetMBSBooleanOptionValue.3=SetMBSBooleanOptionValue failure: No such file exists: +SetMBSStringOptionValue.0=SetMBSStringOptionValue failure: +SetMBSStringOptionValue.3=SetMBSStringOptionValue failure: No such file exists: +SetMBSStringListOptionValues.0=SetMBSStringListOptionValues failure: +SetMBSStringListOptionValues.3=SetMBSStringListOptionValues failure: No such file exists: +NewManagedProject.3=New Project failure: +NewManagedProject.4=New Project failure: +NewManagedProject.5=New Project failure: project already existing in work space: +AppendCreate.1=Add File failure: template source not found: +AppendCreate.2=Append failure: template source not found: +AppendCreate.3=Append failure: cannot read template source: +AppendCreate.4=Append failure: failed while trying to append contents. +AppendToMBSStringOptionValue.0=AppendToMBSStringOptionValue failure: +AppendToMBSStringOptionValue.3=AppendToMBSStringOptionValue failure: No such file exists: +AppendToMBSStringListOptionValues.0=AppendToMBSStringListOptionValues failure: +AppendToMBSStringListOptionValues.3=AppendToMBSStringListOptionValues failure: No such file exists: +CreateSourceFolder.0=Create Source Folder failure: project does not exist: +CreateSourceFolder.1=Create Source Folder failure: +CreateSourceFolder.2=Create Source Folder failure: +CreateIncludeFolder.3=Create Include Folder failure: while setting include path: +ExcludeResources.0=ExcludeResources can only process CDT Managed projects +Copy.0=Add File failure: template source not found: +Copy.1=Copy failure: template source not found: +Copy.3=Copy failure: cannot read template source: +Copy.4=Copy failure: failed while copying contents. +Copy.5=Copy failure: failed while copying contents. +NewProject.7=New Project failure: +NewProject.8=New Project failure: +NewProject.9=New Project failure: project already existing in work space: +Append.0=Add File failure: template source not found: +Append.1=Copy failure: template source not found: +Append.3=Copy failure: cannot read template source: +Append.4=Append failure: failed while trying to append contents. |