blob: f6d321a2b608c0983367fb8aef543d6e009d43f7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2014 Symbian Software Limited and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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.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 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.eclipse.osgi.util.NLS;
/**
* 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 final String TYPE = "type"; //$NON-NLS-1$
private static Map<TemplateInfo, TemplateCore> templateCache = new HashMap<>();
public static final Comparator<TemplateCore> TEMPLATE_ID_CASE_INSENSITIVE_COMPARATOR = new Comparator<>() {
@Override
public int compare(TemplateCore t1, TemplateCore t2) {
return String.CASE_INSENSITIVE_ORDER.compare(t1.getTemplateId(), 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 String templateType;
private boolean fireDirtyEvents;
/**
* @param templateInfo may not be null
* @throws TemplateInitializationException
*/
protected TemplateCore(TemplateInfo templateInfo) throws TemplateInitializationException {
this.templateInfo = templateInfo;
URL descriptorURL;
try {
descriptorURL = TemplateEngineHelper.getTemplateResourceURL(templateInfo.getPluginId(),
templateInfo.getTemplatePath());
} catch (IOException ioe) {
String msg = NLS.bind(Messages.TemplateCore_init_failed, templateInfo.getTemplatePath());
throw new TemplateInitializationException(msg);
}
if (descriptorURL == null)
throw new TemplateInitializationException(
"Unable to load project template. Location URL is null for " + templateInfo.getTemplateId()); //$NON-NLS-1$
templateDescriptor = new TemplateDescriptor(descriptorURL, templateInfo.getPluginId());
valueStore = new ValueStore<>(this);
valueStore.putAll(templateDescriptor.getTemplateDefaults(templateDescriptor.getRootElement()));
valueStore.putAll(TemplateEngine.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<>(allMacrosInProcesses);
for (Iterator<String> 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 TemplateEngineHelper.externalizeTemplateString(templateInfo, 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 id of the template
*/
public String getTemplateType() {
if (templateType == null) {
templateType = templateDescriptor.getRootElement().getAttribute(TYPE).trim();
}
return templateType;
}
/**
* @return String, which contains the Label
*/
public String getLabel() {
if (label == null) {
label = templateDescriptor.getRootElement().getAttribute(LABEL).trim();
}
return TemplateEngineHelper.externalizeTemplateString(templateInfo, label);
}
/**
* TemplateDescriptor for which, this Template is created.
*/
public TemplateProcessHandler getProcessHandler() {
return processHandler;
}
@Override
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, getClass(), IStatus.ERROR, e.getMessage(), e) };
}
return result[0];
}
/**
* Gets the Template
*
* @param templateInfo
* @throws TemplateInitializationException
* @since 4.0
*/
public static TemplateCore getTemplate(TemplateInfo templateInfo) throws TemplateInitializationException {
synchronized (templateCache) {
TemplateCore template = templateCache.get(templateInfo);
if (template == null) {
template = new TemplateCore(templateInfo);
templateCache.put(templateInfo, template);
}
return template;
}
}
private static class ValueStore<K> extends HashMap<K, String> {
private static final long serialVersionUID = -4523467333437879406L;
private TemplateCore template;
ValueStore(TemplateCore template) {
this.template = template;
}
@Override
public String put(K key, String value) {
value = TemplateEngineHelper.externalizeTemplateString(template.getTemplateInfo(), value);
String v = super.put(key, value);
template.setDirty();
return v;
}
@Override
public void putAll(Map<? extends K, ? extends String> map) {
for (K key : map.keySet()) {
String value = map.get(key);
value = TemplateEngineHelper.externalizeTemplateString(template.getTemplateInfo(), value);
super.put(key, value);
}
template.setDirty();
}
@Override
public String remove(Object key) {
String v = super.remove(key);
template.setDirty();
return v;
}
}
}