| /******************************************************************************* |
| * Copyright (c) 2006 Oracle Corporation and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Oracle Corporation |
| *******************************************************************************/ |
| |
| |
| package org.eclipse.bpel.ui; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.net.URL; |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.Set; |
| import java.util.TreeMap; |
| import java.util.TreeSet; |
| |
| import org.osgi.framework.Bundle; |
| |
| /** |
| * You can think of BPEL templates as a 1 dimensional list of stencils that are used |
| * to create an initial BPEL process. |
| * <p> |
| * Each template for a process may contain just 1 resource - just the template for |
| * the BPEL process itself. But it may also contain other resources which are useful |
| * in creating that particular process from that particular template. |
| * Simply put, a template may have 1-N template resources that need to be created |
| * as a result of creating what appears to be a single process file. |
| * |
| * @author Michal Chmielewski (michal.chmielewski@oracle.com) |
| */ |
| |
| public class Templates { |
| |
| /** this file defines the properties for a particular template */ |
| static final String TEMPLATE_PROPERTIES = "template.properties"; //$NON-NLS-1$ |
| |
| /** location within the bundle where we look for templates */ |
| static final String TEMPLATE_LOCATION = "/templates/"; //$NON-NLS-1$ |
| |
| /** default template file encoding, for a given set of template resources */ |
| static final String DEFAULT_ENCODING = "UTF-8"; //$NON-NLS-1$ |
| |
| /** the main bpel file has this extension */ |
| static final String BPEL_FILE_EXTENSION = ".bpel"; //$NON-NLS-1$ |
| |
| /** Entries which are directories of the bundle */ |
| static final String BUNDLE_DIRECTORY = "/"; //$NON-NLS-1$ |
| |
| /** Key or property under which the name of the template is present */ |
| static final String PROPERTY_NAME = "name"; //$NON-NLS-1$ |
| |
| /** The key name of the template */ |
| static final String PROPERTY_KEY = "key"; //$NON-NLS-1$ |
| |
| /** Key or property under which the encoding information for the template resources is present */ |
| static final String PROPERTY_ENCODING = "encoding"; //$NON-NLS-1$ |
| |
| /** Key or property under which the description of the template is present */ |
| static final String PROPERTY_DESCRIPTION = "description"; //$NON-NLS-1$ |
| |
| /** avoid empty string */ |
| static final String EMPTY = ""; //$NON-NLS-1$ |
| |
| static final String[] EMPTY_NAMES = {}; |
| |
| /** Templates contribute namespaces to the new file wizard */ |
| Set<String> mNamespaceNames = new TreeSet<String>(); |
| |
| /** Templates indexed by name, sorted by name, according to the natural ordering */ |
| Map<String,Template> mTemplateByName = new TreeMap<String,Template>(); |
| |
| /** Templates indexed by id, sorted by name */ |
| Map<String,Template> mTemplateByKey = new HashMap<String,Template>(); |
| |
| |
| /** |
| * Initialize the template information from the bundle passed. |
| * This is typically the bundle of the plugin. |
| * |
| * @author Michal Chmielewski (michal.chmielewski@oracle.com) |
| * @param bundle the bundle where the template information ought to be looked for |
| */ |
| |
| @SuppressWarnings("nls") |
| public void initializeFrom ( Bundle bundle ) |
| { |
| initializeFrom(bundle, TEMPLATE_LOCATION); |
| } |
| |
| /** |
| * @param templateLocation |
| */ |
| |
| public void initializeFrom ( String templateLocation ) { |
| initializeFrom(BPELUIPlugin.INSTANCE.getBundle(), templateLocation); |
| } |
| |
| /** |
| * @param bundle |
| * @param templateLocation |
| */ |
| |
| @SuppressWarnings({ "nls", "boxing" }) |
| public void initializeFrom (Bundle bundle, String templateLocation ) { |
| |
| Enumeration<String> list = bundle.getEntryPaths( templateLocation ); |
| if (list == null) { |
| return ; |
| } |
| // got some elements, look for "template.properties" |
| |
| int count = 0; |
| |
| while (list.hasMoreElements()) { |
| String nextRoot = list.nextElement(); |
| if ( nextRoot.endsWith(BUNDLE_DIRECTORY) == false ) { |
| continue; |
| } |
| |
| String nextEntry = nextRoot + TEMPLATE_PROPERTIES; |
| // found another template |
| |
| URL nextURL = bundle.getEntry(nextEntry); |
| if (nextURL == null) { |
| // no such thing |
| continue; |
| } |
| |
| // looks like we have properties |
| count += 1; |
| |
| Properties props = new Properties (); |
| InputStream is = null; |
| |
| try { |
| is = nextURL.openStream(); |
| props.load( is ); |
| } catch (IOException e) { |
| BPELUIPlugin.log(e); |
| |
| |
| // skip to the next entry |
| continue; |
| |
| } finally { |
| try { is.close() ; } catch (Throwable t) {} |
| } |
| |
| |
| String name = props.getProperty(PROPERTY_NAME); |
| |
| // No name, no game. |
| if (name == null) { |
| continue ; |
| } |
| |
| |
| String enc = props.getProperty(PROPERTY_ENCODING,DEFAULT_ENCODING); |
| String desc = props.getProperty(PROPERTY_DESCRIPTION,EMPTY); |
| |
| |
| // add any namespaces we are supplying ... |
| mNamespaceNames.addAll( findProperties (props,"namespace.{0}") ); |
| |
| Template template = new Template(); |
| template.mName = name; |
| template.mDescription = desc; |
| template.mProperties = (Map) props; |
| |
| mTemplateByName.put ( name, template ); |
| String id = props.getProperty(PROPERTY_KEY); |
| if (id != null) { |
| mTemplateByKey.put ( id, template ); |
| } |
| |
| |
| int hole = 3; |
| for(int i=0; hole >= 0; i++) { |
| String key = MessageFormat.format("resource.{0}",i); |
| String resourceName = props.getProperty(key); |
| if (resourceName == null) { |
| hole--; |
| continue; |
| } |
| hole = 3; |
| |
| key = MessageFormat.format("resource.{0}.name", i); |
| String nameTemplate = props.getProperty(key); |
| |
| String entryLoc = nextRoot + resourceName; |
| |
| TemplateResource resource = new TemplateResource() ; |
| resource.mName = resourceName; |
| resource.mContent = slurpContent ( bundle.getEntry(entryLoc), enc ); |
| resource.mNameTemplate = nameTemplate ; |
| |
| // add the resource which makes up this "template" |
| template.add ( resource ); |
| |
| } |
| |
| } |
| |
| } |
| |
| |
| /** |
| * Slurp the resource into memory and return as a String. If an exception |
| * occurs, it is logged, and the return value is empty string. |
| * |
| * @param loc the location from which we should slurp ... |
| * @param enc the encoding to use |
| * @return the text |
| */ |
| |
| String slurpContent ( URL loc, String enc) { |
| |
| if (loc == null) { |
| return null; |
| } |
| |
| StringBuilder sb = new StringBuilder ( 2 * 1048 ); |
| char[] buf = new char[ 256 ]; |
| InputStreamReader isr = null; |
| |
| try { |
| isr = new InputStreamReader ( loc.openStream(), enc); |
| |
| do { |
| int cnt = isr.read(buf); |
| if (cnt < 0) { |
| break; |
| } |
| sb.append( buf, 0, cnt ); |
| } while (true); |
| |
| } catch (Exception ex) { |
| BPELUIPlugin.log(ex); |
| } finally { |
| try {isr.close(); } catch (Throwable t) {} |
| } |
| |
| |
| return sb.toString(); |
| } |
| |
| |
| |
| |
| List<String> findProperties ( Properties props, String pattern ) { |
| |
| List<String> list = new ArrayList<String>(); |
| int hole = 3; |
| |
| for(int i=0; hole >= 0; i++) { |
| |
| String key = MessageFormat.format(pattern, new Object[] { new Integer(i) } ); |
| String val = props.getProperty(key,null); |
| if (val != null) { |
| list.add ( val ); |
| hole = 3; |
| } else { |
| hole--; |
| } |
| } |
| |
| return list; |
| } |
| |
| /** |
| * @param key |
| * @return the template whose key is key |
| */ |
| |
| public Template getTemplateByKey ( String key ) { |
| return mTemplateByKey.get(key); |
| } |
| |
| |
| /** |
| * Return the template definition (which includes other resources that |
| * may be present) to the caller. |
| * |
| * @param name name of the template |
| * @return the template definition, including template resources |
| */ |
| |
| public Template getTemplateByName ( String name ) |
| { |
| return mTemplateByName.get(name); |
| } |
| |
| |
| /** |
| * |
| * @return Return the namespaces contributed by the templates. |
| */ |
| |
| public String[] getNamespaceNames () |
| { |
| return mNamespaceNames.toArray( EMPTY_NAMES ); |
| } |
| |
| |
| |
| /** |
| * Return the template names that have been discovered. |
| * |
| * @return Return the template names. |
| */ |
| |
| public String [] getTemplateNames () |
| { |
| return mTemplateByName.keySet().toArray( EMPTY_NAMES ); |
| } |
| |
| |
| |
| /** |
| * A given "BPEL Process" Template has a name, description, and |
| * a list of resources (file templates) that will be used to create the initial |
| * process source file. |
| * |
| * @author Michal Chmielewski (michal.chmielewski@oracle.com) |
| * |
| */ |
| |
| public class Template { |
| |
| /** Name of the process template */ |
| String mName; |
| |
| /** Description of this process template */ |
| String mDescription ; |
| |
| Map<String,String> mProperties ; |
| |
| /** list of resources that this template has (1-N) */ |
| List<TemplateResource> mResources = new ArrayList<TemplateResource>(); |
| |
| |
| /** |
| * @return the name |
| */ |
| public String getName() { |
| return mName; |
| } |
| |
| |
| void add ( TemplateResource resource ) { |
| mResources.add(resource); |
| resource.mTemplate = this; |
| } |
| |
| /** |
| * @return the template resources |
| */ |
| public List<TemplateResource> getResources() { |
| return mResources; |
| } |
| |
| /** |
| * @return the description |
| */ |
| public String getDescription() { |
| return mDescription; |
| } |
| |
| /** |
| * Return the property under the key or null if not found. |
| * @param key |
| * @return the property under the key, or null. |
| */ |
| |
| public String getProperty ( String key ) { |
| return mProperties.get(key); |
| } |
| |
| |
| TemplateResource lookupResource ( String name ) { |
| String name2 = mProperties.get(name); |
| for (TemplateResource resource : mResources) { |
| if (name.equals(resource.mName)) { |
| return resource; |
| } |
| if (name2 != null && name2.equals(resource.mName)) { |
| return resource; |
| } |
| } |
| return null; |
| } |
| |
| } |
| |
| /** |
| * A template resource is the actual file which will be used to create |
| * the source file or other auxiliary files for the BPEL process source. |
| * |
| * @author Michal Chmielewski, (michal.chmielewski@oracle.com) |
| * |
| */ |
| |
| public class TemplateResource { |
| |
| /** The template I belong to */ |
| Template mTemplate = null; |
| |
| /** Name of the resource (from the bundle) */ |
| String mName ; |
| |
| /** The content of the resource (slurped from the bundle) */ |
| String mContent; |
| |
| /** The name template, that is, the file name template if depended on process name */ |
| String mNameTemplate; |
| |
| /** |
| * @return the content |
| */ |
| public String getContent() { |
| return mContent; |
| } |
| |
| /** |
| * @return the name |
| */ |
| public String getName() { |
| return mName; |
| } |
| |
| |
| /** |
| * Process the content of the template and replace anything within |
| * ${...} by the corresponding key prent in the map passed. |
| * |
| * @param args the keys that will be replaced in the content |
| * @return the replaced content |
| */ |
| |
| public String process ( Map<String,Object> args ) { |
| |
| return process ( mContent, args ); |
| } |
| |
| |
| /** |
| * Process the content of the template and replace anything within |
| * ${...} by the corresponding key present in the map passed. |
| * |
| * @param args the keys that will be replaced in the content |
| * @return the replaced content |
| */ |
| |
| @SuppressWarnings("nls") |
| String process (String src, Map<String,Object> args ) |
| { |
| // empty content, empty result |
| if (src == null) { |
| return ""; |
| } |
| StringBuilder sb = new StringBuilder ( src.length() ); |
| int cursor = 0; |
| do { |
| int openReplace = src.indexOf("${", cursor); |
| if (openReplace < 0) { |
| break; |
| } |
| sb.append( src.substring(cursor,openReplace)); |
| cursor = openReplace + 2; |
| int closeReplace = src.indexOf("}",cursor); |
| if (closeReplace < 0) { |
| return sb.toString(); |
| } |
| |
| String expr = src.substring(cursor, closeReplace).trim() ; |
| sb.append( lookup(expr,args) ); |
| |
| cursor = closeReplace + 1; |
| } while (true); |
| |
| // the last segment |
| sb.append( src.substring(cursor) ); |
| return sb.toString(); |
| } |
| |
| |
| @SuppressWarnings("nls") |
| |
| Object lookup ( String key, Map<String,Object> args) { |
| Object value = null; |
| TemplateResource r = null; |
| if (key.startsWith(":include:")) { |
| key = key.substring(9); |
| r = mTemplate.lookupResource(key); |
| if (r != null) { |
| value = r.mContent; |
| } |
| } else if (key.startsWith(":parse:")) { |
| key = key.substring(7); |
| r = mTemplate.lookupResource (key); |
| /** Avoid recursion at this point */ |
| if (r != null && r != this) { |
| value = r.process( args ); |
| } |
| } else { |
| value = args.get(key); |
| if (value == null) { |
| value = mTemplate.mProperties.get(key); |
| } |
| } |
| return value; |
| } |
| |
| /** |
| * Return the name of the resource |
| * |
| * @param args map of arguments that are used in replacing |
| * @return the name of the resource, after token replacement. |
| */ |
| |
| public String getName (Map<String,Object> args) { |
| |
| if (mNameTemplate == null) { |
| return mName; |
| } |
| return process (mNameTemplate, args); |
| } |
| |
| |
| /** |
| * Ask if this TemplateResource is specifically a BPEL source file. |
| * |
| * @return Answer true if the extension is .bpel |
| */ |
| |
| public boolean isProcess() |
| { |
| return mName.endsWith( BPEL_FILE_EXTENSION ); |
| } |
| } |
| |
| } |