qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ai...@apache.org
Subject svn commit: r651133 [2/17] - in /incubator/qpid/trunk/qpid: gentools/ gentools/src/org/apache/qpid/gentools/ java/ java/broker/ java/broker/src/main/grammar/ java/broker/src/main/java/org/apache/qpid/server/exchange/ java/broker/src/main/java/org/apach...
Date Thu, 24 Apr 2008 01:54:42 GMT
Modified: incubator/qpid/trunk/qpid/gentools/src/org/apache/qpid/gentools/Generator.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/src/org/apache/qpid/gentools/Generator.java?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/gentools/src/org/apache/qpid/gentools/Generator.java (original)
+++ incubator/qpid/trunk/qpid/gentools/src/org/apache/qpid/gentools/Generator.java Wed Apr 23 18:54:20 2008
@@ -1,848 +1,857 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.gentools;
-
-import org.apache.velocity.Template;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.Velocity;
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.LineNumberReader;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-
-public abstract class Generator implements LanguageConverter
-{
-    protected static String CR = Utils.LINE_SEPARATOR;
-
-
-    private static final Map<String, Integer> FIXED_SIZE_TYPES = new HashMap<String, Integer>();
-
-    static
-    {
-        FIXED_SIZE_TYPES.put("bit", 1);
-        FIXED_SIZE_TYPES.put("bitfield", 1);
-        FIXED_SIZE_TYPES.put("long", 4);
-        FIXED_SIZE_TYPES.put("longlong", 8);
-        FIXED_SIZE_TYPES.put("octet", 1);
-        FIXED_SIZE_TYPES.put("short", 2);
-        FIXED_SIZE_TYPES.put("timestamp", 8);
-
-    }
-
-    private String _templateDirectory;
-    private String _outputDirectory;
-
-    public AmqpDomainMap getDomainMap()
-    {
-        return _domainMap;
-    }
-
-    public AmqpConstantSet getConstantSet()
-    {
-        return _constantSet;
-    }
-
-    public AmqpModel getModel()
-    {
-        return _model;
-    }
-
-    abstract public String getNativeType(String type);
-
-    abstract public String getEncodingType(String type);
-
-
-
-    protected static enum EnumConstOutputTypes
-    {
-        OUTPUT_STRING,
-        OUTPUT_INTEGER,
-        OUTPUT_DOUBLE;
-    }
-
-    ;
-
-    public static enum TemplateType
-    {
-        model("model"),
-        clazz("class"),
-        method("method"),
-        field("field");
-
-        private final String _name;
-
-        private TemplateType(String name)
-        {
-            _name = name;
-        }
-
-        public String getName()
-        {
-            return _name;
-        }
-    }
-
-    ;
-
-
-    public static interface Factory<X extends Generator>
-    {
-        public X newInstance();
-    }
-
-
-    protected static final class NamedTemplate
-    {
-        private final String _name;
-        private final String _template;
-        private final File _file;
-
-
-        public NamedTemplate(String relativePath, File templateFile)
-        {
-            _file = templateFile;
-            _name = relativePath + Utils.FILE_SEPARATOR + templateFile.getName();
-
-            _template = loadTemplate(templateFile);
-        }
-
-
-        public String getName()
-        {
-            return _name;
-        }
-
-        public String getTemplate()
-        {
-            return _template;
-        }
-
-
-        public File getFile()
-        {
-            return _file;
-        }
-
-    }
-
-
-    private static final String VELOCITY_TEMPLATE_SUFFIX = ".vm";
-    private static final String STANDARD_TEMPLATE_SUFFIX = ".tmpl";
-    private static FilenameFilter _tmplFileFilter = new FilenameFilter()
-    {
-
-        public boolean accept(File dir, String name)
-        {
-            return name.endsWith(STANDARD_TEMPLATE_SUFFIX) || name.endsWith(VELOCITY_TEMPLATE_SUFFIX);
-        }
-    };
-
-
-    // This string is reproduced in every generated file as a comment
-    // TODO: Tie the version info into the build system.
-    protected static final String GENERATOR_INFO = "Qpid Gentools v.0.1";
-
-
-    private final Map<TemplateType, Collection<NamedTemplate>> _templates =
-            new EnumMap<TemplateType, Collection<NamedTemplate>>(TemplateType.class);
-
-    private final Map<TemplateType, Collection<NamedTemplate>> _versionSpecificTemplates =
-            new EnumMap<TemplateType, Collection<NamedTemplate>>(TemplateType.class);
-
-
-    private final AmqpVersionSet _versionSet;
-
-    private final AmqpDomainMap _domainMap;
-    private final Map<AmqpVersion, AmqpDomainMap> _versionToDomainMapMap = new HashMap<AmqpVersion, AmqpDomainMap>();
-
-    private final AmqpConstantSet _constantSet;
-    private final Map<AmqpVersion, AmqpConstantSet> _versionToConstantSetMap = new HashMap<AmqpVersion, AmqpConstantSet>();
-
-
-    public AmqpVersionSet getVersionSet()
-    {
-        return _versionSet;
-    }
-
-    private final AmqpModel _model;
-    private final Map<AmqpVersion, AmqpModel> _versionToModelMap = new HashMap<AmqpVersion, AmqpModel>();
-
-    protected int generatedFileCounter;
-
-    public Generator()
-    {
-        _versionSet = new AmqpVersionSet();
-        _model = new AmqpModel(this);
-        _constantSet = new AmqpConstantSet(this);
-        _domainMap = new AmqpDomainMap(this);
-
-        generatedFileCounter = 0;
-    }
-
-//    public final AmqpVersionSet getVersionSet()
-//    {
-//        return _versionSet;
-//    }
-
-
-    public void addVersion(AmqpVersion version)
-    {
-        _versionSet.add(version);
-        if (!_versionToModelMap.containsKey(version))
-        {
-            _versionToModelMap.put(version, new AmqpModel(this));
-        }
-        if (!_versionToDomainMapMap.containsKey(version))
-        {
-            _versionToDomainMapMap.put(version, new AmqpDomainMap(this));
-        }
-        if (!_versionToConstantSetMap.containsKey(version))
-        {
-            _versionToConstantSetMap.put(version, new AmqpConstantSet(this));
-        }
-    }
-
-    public int getNumberGeneratedFiles()
-    {
-        return generatedFileCounter;
-    }
-
-//	public AmqpDomainMap getDomainMap()
-//	{
-//		return _domainMap;
-//	}
-//
-//    public AmqpConstantSet getConstantSet()
-//    {
-//        return _constantSet;
-//    }
-//
-//
-//	public AmqpModel getModel()
-//	{
-//		return _model;
-//	}
-
-    public void initializeTemplates() throws IOException
-    {
-
-        for (TemplateType type : EnumSet.allOf(TemplateType.class))
-        {
-            ArrayList<NamedTemplate> typeTemplates = new ArrayList<NamedTemplate>();
-            _templates.put(type, typeTemplates);
-            ArrayList<NamedTemplate> versionSpecificTypeTemplates = new ArrayList<NamedTemplate>();
-            _versionSpecificTemplates.put(type, versionSpecificTypeTemplates);
-
-            File templateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName());
-            File versionTemplateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName() + Utils.FILE_SEPARATOR + "version");
-
-            File[] templateFiles = templateDirectory.listFiles(_tmplFileFilter);
-
-            File[] versionTemplateFiles = new File[0];
-            if (versionTemplateDirectory.exists())
-            {
-                versionTemplateFiles = versionTemplateDirectory.listFiles(_tmplFileFilter);
-            }
-
-			if(templateFiles != null)
-			{
-	            for (File templateFile : templateFiles)
-	            {
-	                System.out.println(type.getName() + " template file(s):");
-	                System.out.println("  " + templateFile.getCanonicalPath());
-	                typeTemplates.add(new NamedTemplate(type.getName(), templateFile));
-	            }
-			}
-
-            if(versionTemplateFiles != null)
-			{
-				for (File versionTemplateFile : versionTemplateFiles)
-	            {
-	                System.out.println(type.getName() + " template file(s):");
-	                System.out.println("  " + versionTemplateFile.getCanonicalPath());
-	                versionSpecificTypeTemplates.add(new NamedTemplate(type.getName() + Utils.FILE_SEPARATOR + "version", versionTemplateFile));
-	            }
-			}
-
-        }
-    }
-
-    public String getTemplateDirectory()
-    {
-        return _templateDirectory;
-    }
-
-
-    public void setTemplateDirectory(String templateDirectory)
-    {
-        _templateDirectory = templateDirectory;
-    }
-
-
-    public void setOutputDirectory(String outputDirectory)
-    {
-        _outputDirectory = outputDirectory;
-    }
-
-    public void generate()
-    {
-        prepareTargetDirectory(new File(_outputDirectory), true);
-        System.out.println("Generation directory: " + _outputDirectory);
-
-
-        processModelTemplates(_templates);
-
-        for (AmqpClass amqpClass : _model.getClassMap().values())
-        {
-            processClassTemplates(_templates, amqpClass);
-
-            for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values())
-            {
-                processMethodTemplates(_templates, amqpClass, amqpMethod);
-
-                for (AmqpField amqpField : amqpMethod.getFieldMap().values())
-                {
-                    processFieldTemplates(_templates, amqpClass, amqpMethod, amqpField, null);
-                }
-            }
-        }
-
-
-        for (AmqpVersion version : _versionSet)
-        {
-            AmqpModel model = _versionToModelMap.get(version);
-            processModelTemplates(_versionSpecificTemplates, version);
-
-            for (AmqpClass amqpClass : model.getClassMap().values())
-            {
-                processClassTemplates(_versionSpecificTemplates, amqpClass, version);
-
-                for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values())
-                {
-                    processMethodTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, version);
-
-                    for (AmqpField amqpField : amqpMethod.getFieldMap().values())
-                    {
-                        processFieldTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, amqpField, version);
-                    }
-                }
-            }
-
-        }
-    }
-
-    private void processMethodTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version)
-    {
-        for (NamedTemplate template : templates.get(TemplateType.method))
-        {
-            if(isVelocityTemplate(template))
-            {
-                processVelocityTemplate(template,version,amqpClass,amqpMethod,null);
-            }
-            else
-            {
-                processMethodTemplate(template, amqpClass, amqpMethod);
-            }
-        }
-        
-    }
-
-    private void processClassTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpVersion version)
-    {
-        for (NamedTemplate template : templates.get(TemplateType.clazz))
-        {
-            if(isVelocityTemplate(template))
-            {
-                processVelocityTemplate(template,version,amqpClass,null,null);
-            }
-            else
-            {
-                processClassTemplate(template, amqpClass);
-            }
-        }
-
-    }
-
-
-    private void processModelTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpVersion version)
-    {
-        for (NamedTemplate template : templates.get(TemplateType.model))
-        {
-            if (isVelocityTemplate(template))
-            {
-                processModelVelocityTemplate(template, version);
-            }
-            else
-            {
-                processModelTemplate(template, version);
-            }
-        }
-    }
-
-    abstract void processModelTemplate(NamedTemplate template, AmqpVersion version);
-
-
-    protected void processModelTemplates(Map<TemplateType, Collection<NamedTemplate>> templates)
-    {
-        for (NamedTemplate template : templates.get(TemplateType.model))
-        {
-            if (isVelocityTemplate(template))
-            {
-                processModelVelocityTemplate(template, null);
-            }
-            else
-            {
-                processModelTemplate(template);
-            }
-        }
-    }
-
-    private boolean isVelocityTemplate(NamedTemplate template)
-    {
-        return template.getName().endsWith(VELOCITY_TEMPLATE_SUFFIX);
-    }
-
-    private void processModelVelocityTemplate(NamedTemplate template, AmqpVersion version)
-    {
-        processVelocityTemplate(template,version,null,null,null);
-    }
-
-    private void processVelocityTemplate(NamedTemplate template, AmqpVersion version,
-                                              AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField)
-    {
-
-        VelocityContext context = new VelocityContext();
-
-        AmqpModel model = _model;
-        if(version != null)
-        {
-            model = _versionToModelMap.get(version);
-        }
-        context.put("model", model);
-        context.put("generator", GENERATOR_INFO);
-
-        if (version != null)
-        {
-            context.put("version", version);
-        }
-        if(amqpClass != null)
-        {
-            context.put("amqpClass", amqpClass);
-        }
-
-        if(amqpClass != null)
-        {
-            context.put("amqpMethod", amqpMethod);
-        }
-
-
-        StringWriter sw = new StringWriter();
-
-
-        try
-        {
-            Template velocityTemplate = Velocity.getTemplate(template.getName());
-            velocityTemplate.merge(context, sw);
-            String filename = String.valueOf(context.get("filename"));
-            FileWriter outputFileWriter = new FileWriter(getOutputDirectory() + Utils.FILE_SEPARATOR + filename);
-            outputFileWriter.append(sw.toString());
-            outputFileWriter.close();
-
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-
-
-    }
-
-
-    protected void processClassTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass)
-    {
-        for (NamedTemplate template : templates.get(TemplateType.clazz))
-        {
-            if(isVelocityTemplate(template))
-            {
-                processVelocityTemplate(template,null,amqpClass,null,null);
-            }
-            else
-            {
-                processClassTemplate(template, amqpClass);
-            }
-        }
-    }
-
-    protected void processMethodTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod)
-    {
-        for (NamedTemplate template : templates.get(TemplateType.method))
-        {
-            if(isVelocityTemplate(template))
-            {
-                processVelocityTemplate(template,null,amqpClass,amqpMethod,null);
-            }
-            else
-            {
-                processMethodTemplate(template, amqpClass, amqpMethod);
-            }
-        }
-    }
-
-
-    protected void processFieldTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion amqpVersion)
-    {
-        for (NamedTemplate template : templates.get(TemplateType.field))
-        {
-            if(isVelocityTemplate(template))
-            {
-                processVelocityTemplate(template,amqpVersion,amqpClass,amqpMethod,amqpField);
-            }
-            else
-            {
-                processTemplate(template, amqpClass, amqpMethod, amqpField, amqpVersion);
-            }
-        }
-    }
-
-
-    protected void processVersionList(StringBuffer sb, int tokStart, int tokEnd)
-    {
-        int lend = sb.indexOf(Utils.LINE_SEPARATOR, tokStart) + 1; // Include cr at end of line
-        String tline = sb.substring(tokEnd, lend); // Line excluding line marker, including cr
-        sb.delete(tokStart, lend);
-
-        for (AmqpVersion v : _versionSet)
-        {
-            // Insert copy of target line
-            StringBuffer isb = new StringBuffer(tline);
-            if (isb.indexOf("${protocol-version-list-entry}") >= 0)
-            {
-                String versionListEntry = "       { ${major}, ${minor} }" +
-                                          (v.equals(_versionSet.last()) ? "" : ",");
-                replaceToken(isb, "${protocol-version-list-entry}", String.valueOf(versionListEntry));
-            }
-            if (isb.indexOf("${major}") >= 0)
-            {
-                replaceToken(isb, "${major}", String.valueOf(v.getMajor()));
-            }
-            if (isb.indexOf("${minor}") >= 0)
-            {
-                replaceToken(isb, "${minor}", String.valueOf(v.getMinor()));
-            }
-            sb.insert(tokStart, isb.toString());
-            tokStart += isb.length();
-        }
-    }
-
-    // Helper functions common to all generators
-
-    protected static void prepareTargetDirectory(File dir, boolean createFlag)
-    {
-        if (dir.exists())
-        {
-            if (!dir.isDirectory())
-            {
-                throw new TargetDirectoryException("\"" + dir.getAbsolutePath() +
-                                                   "\" exists, but is not a directory.");
-            }
-        }
-        else if (createFlag) // Create dir
-        {
-            if (!dir.mkdirs())
-            {
-                throw new TargetDirectoryException("Unable to create directory \"" +
-                                                   dir.getAbsolutePath() + "\".");
-            }
-        }
-        else
-        {
-            throw new TargetDirectoryException("Directory \"" + dir.getAbsolutePath() +
-                                               "\" not found.");
-        }
-
-    }
-
-    protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpVersion version)
-    {
-        AmqpModel model = (version == null) ? _model : _versionToModelMap.get(version);
-
-
-        int lstart = sb.indexOf("%{");
-        while (lstart != -1)
-        {
-            int lend = sb.indexOf("}", lstart + 2);
-            if (lend > 0)
-            {
-                String listToken = sb.substring(lstart + 2, lend);
-                if (listToken.compareTo("VLIST") == 0)
-                {
-                    processVersionList(sb, lstart, lend + 1);
-                }
-                else if (listToken.compareTo("CLIST") == 0)
-                {
-                    processClassList(sb, lstart, lend + 1, model, version);
-                }
-                else if (listToken.compareTo("MLIST") == 0)
-                {
-                    processMethodList(sb, lstart, lend + 1, thisClass);
-                }
-                else if (listToken.compareTo("FLIST") == 0)
-                {
-                    // Pass the FieldMap from either a class or a method.
-                    // If this is called from a class-level template, we assume that the
-                    // class field list is required. In this case, method will be null.
-                    processFieldList(sb, lstart, lend + 1,
-                                     (method == null ? thisClass.getFieldMap() : method.getFieldMap()),
-                                     version);
-                }
-                else if (listToken.compareTo("TLIST") == 0)
-                {
-                    processConstantList(sb, lstart, lend + 1, _constantSet);
-                }
-                else
-                {
-                    throw new AmqpTemplateException("Unknown list token \"%{" + listToken +
-                                                    "}\" found in template at index " + lstart + ".");
-                }
-            }
-            lstart = sb.indexOf("%{", lstart + 1);
-        }
-    }
-
-    protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field,
-                                    AmqpVersion version)
-    {
-        int lstart = sb.indexOf("${");
-        while (lstart != -1)
-        {
-            int lend = sb.indexOf("}", lstart + 2);
-            if (lend > 0)
-            {
-                String token = sb.substring(lstart, lend + 1);
-                replaceToken(sb, lstart, token, processToken(token, thisClass, method, field, version));
-            }
-            lstart = sb.indexOf("${", lstart);
-        }
-    }
-
-    protected static void writeTargetFile(StringBuffer sb, File f)
-    {
-        try
-        {
-            f.getParentFile().mkdirs();
-            FileWriter fw = new FileWriter(f);
-            fw.write(sb.toString().toCharArray());
-            fw.flush();
-            fw.close();
-        }
-        catch (IOException e)
-        {
-            throw new AmqpTemplateException(e.getMessage());
-        }
-    }
-
-
-    protected static String getTemplateFileName(StringBuffer sb)
-    {
-        if (sb.charAt(0) != '&')
-        {
-            throw new AmqpTemplateException("No filename marker &{filename} found at start of template.");
-        }
-        int cr = sb.indexOf(Utils.LINE_SEPARATOR);
-        if (cr < 0)
-        {
-            throw new AmqpTemplateException("Bad template structure - unable to find first line.");
-        }
-        String fileName = sb.substring(2, cr - 1);
-        sb.delete(0, cr + 1);
-        return fileName;
-    }
-
-    protected static void replaceToken(StringBuffer sb, String token, String replacement)
-    {
-        replaceToken(sb, 0, token, replacement);
-    }
-
-    protected static void replaceToken(StringBuffer sb, int index, String token, String replacement)
-    {
-        if (replacement != null)
-        {
-            int start = sb.indexOf(token, index);
-            if (start != -1)
-            {
-                int len = token.length();
-                // Find first letter in token and determine if it is capitalized
-                char firstTokenLetter = getFirstLetter(token);
-                if (firstTokenLetter != 0 && Character.isUpperCase(firstTokenLetter))
-                {
-                    sb.replace(start, start + len, Utils.firstUpper(replacement));
-                }
-                else
-                {
-                    sb.replace(start, start + len, replacement);
-                }
-            }
-        }
-    }
-
-    private static char getFirstLetter(String str)
-    {
-        int len = str.length();
-        int index = 0;
-        char tokChar = str.charAt(index);
-        while (!Character.isLetter(tokChar) && index < len - 1)
-        {
-            tokChar = str.charAt(++index);
-        }
-        if (Character.isLetter(tokChar))
-        {
-            return tokChar;
-        }
-        return 0;
-    }
-
-    private static String loadTemplate(File f)
-    {
-        try
-        {
-            StringBuffer sb = new StringBuffer();
-            FileReader fr = new FileReader(f);
-            LineNumberReader lnr = new LineNumberReader(fr);
-            String line = lnr.readLine();
-            while (line != null)
-            {
-
-                sb.append(line);
-                sb.append(Utils.LINE_SEPARATOR);
-
-                line = lnr.readLine();
-            }
-            lnr.close();
-            fr.close();
-            return sb.toString();
-        }
-        catch (FileNotFoundException e)
-        {
-            throw new AmqpTemplateException("File not found: " + e.getMessage());
-        }
-        catch (IOException e)
-        {
-            throw new AmqpTemplateException("IOException: " + e.getMessage());
-        }
-    }
-
-    public String getDomainType(String domainName, AmqpVersion version)
-    {
-        if (version == null)
-        {
-            version = _versionSet.first();
-        }
-        return getDomainMap().getDomainType(domainName, version);
-    }
-
-
-    public void addFromNode(Node amqpNode, AmqpVersion version)
-    {
-        // 1c. Extract domains
-        getConstantSet().addFromNode(amqpNode, 0, version);
-        _versionToConstantSetMap.get(version).addFromNode(amqpNode, 0, version);
-
-        // 1d. Extract domains
-        getDomainMap().addFromNode(amqpNode, 0, version);
-        _versionToDomainMapMap.get(version).addFromNode(amqpNode, 0, version);
-
-        // 1e. Extract class/method/field heirarchy
-        getModel().addFromNode(amqpNode, 0, version);
-        _versionToModelMap.get(version).addFromNode(amqpNode, 0, version);
-    }
-
-
-    public String getOutputDirectory()
-    {
-        return _outputDirectory;
-    }
-
-    public String prepareConstantName(String constantName)
-    {
-        return prepareDomainName(constantName);
-    }
-
-
-    public boolean isFixedSizeType(String type)
-    {
-        return FIXED_SIZE_TYPES.containsKey(type);
-    }
-
-
-    public int getTypeSize(String type)
-    {
-        return FIXED_SIZE_TYPES.get(type);
-    }
-
-
-
-    // Model-level template processing
-    abstract protected void processModelTemplate(NamedTemplate template);
-
-    // Class-level template processing
-    abstract protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass);
-
-    // Method-level template processing
-    abstract protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass,
-                                                  AmqpMethod method);
-
-    // Field-level template processing
-    abstract protected void processTemplate(NamedTemplate template, AmqpClass thisClass,
-                                            AmqpMethod method, AmqpField field, AmqpVersion version);
-
-    abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method,
-                                              AmqpField field, AmqpVersion version);
-
-    abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method,
-                                           AmqpField field, AmqpVersion version);
-
-    abstract protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
-                                             AmqpModel model, AmqpVersion version);
-
-    abstract protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
-                                              AmqpClass thisClass);
-
-
-    abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
-                                             AmqpFieldMap fieldMap, AmqpVersion version);
-
-    abstract protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
-                                                AmqpConstantSet constantSet);
-
-
-}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.w3c.dom.Node;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class Generator implements LanguageConverter
+{
+    protected static String CR = Utils.LINE_SEPARATOR;
+
+
+    private static final Map<String, Integer> FIXED_SIZE_TYPES = new HashMap<String, Integer>();
+
+    static
+    {
+        FIXED_SIZE_TYPES.put("bit", 1);
+        FIXED_SIZE_TYPES.put("bitfield", 1);
+        FIXED_SIZE_TYPES.put("long", 4);
+        FIXED_SIZE_TYPES.put("longlong", 8);
+        FIXED_SIZE_TYPES.put("octet", 1);
+        FIXED_SIZE_TYPES.put("short", 2);
+        FIXED_SIZE_TYPES.put("timestamp", 8);
+
+    }
+
+    private String _templateDirectory;
+    private String _outputDirectory;
+
+    public AmqpDomainMap getDomainMap()
+    {
+        return _domainMap;
+    }
+
+    public AmqpConstantSet getConstantSet()
+    {
+        return _constantSet;
+    }
+
+    public AmqpModel getModel()
+    {
+        return _model;
+    }
+
+    abstract public String getNativeType(String type);
+
+    abstract public String getEncodingType(String type);
+
+
+
+    protected static enum EnumConstOutputTypes
+    {
+        OUTPUT_STRING,
+        OUTPUT_INTEGER,
+        OUTPUT_DOUBLE;
+    }
+
+    ;
+
+    public static enum TemplateType
+    {
+        model("model"),
+        clazz("class"),
+        method("method"),
+        field("field");
+
+        private final String _name;
+
+        private TemplateType(String name)
+        {
+            _name = name;
+        }
+
+        public String getName()
+        {
+            return _name;
+        }
+    }
+
+    ;
+
+
+    public static interface Factory<X extends Generator>
+    {
+        public X newInstance();
+    }
+
+
+    protected static final class NamedTemplate
+    {
+        private final String _name;
+        private final String _template;
+        private final File _file;
+
+
+        public NamedTemplate(String relativePath, File templateFile)
+        {
+            _file = templateFile;
+            _name = relativePath + Utils.FILE_SEPARATOR + templateFile.getName();
+
+            _template = loadTemplate(templateFile);
+        }
+
+
+        public String getName()
+        {
+            return _name;
+        }
+
+        public String getTemplate()
+        {
+            return _template;
+        }
+
+
+        public File getFile()
+        {
+            return _file;
+        }
+
+    }
+
+
+    private static final String VELOCITY_TEMPLATE_SUFFIX = ".vm";
+    private static final String STANDARD_TEMPLATE_SUFFIX = ".tmpl";
+    private static FilenameFilter _tmplFileFilter = new FilenameFilter()
+    {
+
+        public boolean accept(File dir, String name)
+        {
+            return name.endsWith(STANDARD_TEMPLATE_SUFFIX) || name.endsWith(VELOCITY_TEMPLATE_SUFFIX);
+        }
+    };
+
+
+    // This string is reproduced in every generated file as a comment
+    // TODO: Tie the version info into the build system.
+    protected static final String GENERATOR_INFO = "Qpid Gentools v.0.1";
+
+
+    private final Map<TemplateType, Collection<NamedTemplate>> _templates =
+            new EnumMap<TemplateType, Collection<NamedTemplate>>(TemplateType.class);
+
+    private final Map<TemplateType, Collection<NamedTemplate>> _versionSpecificTemplates =
+            new EnumMap<TemplateType, Collection<NamedTemplate>>(TemplateType.class);
+
+
+    private final AmqpVersionSet _versionSet;
+
+    private final AmqpDomainMap _domainMap;
+    private final Map<AmqpVersion, AmqpDomainMap> _versionToDomainMapMap = new HashMap<AmqpVersion, AmqpDomainMap>();
+
+    private final AmqpConstantSet _constantSet;
+    private final Map<AmqpVersion, AmqpConstantSet> _versionToConstantSetMap = new HashMap<AmqpVersion, AmqpConstantSet>();
+
+
+    public AmqpVersionSet getVersionSet()
+    {
+        return _versionSet;
+    }
+
+    private final AmqpModel _model;
+    private final Map<AmqpVersion, AmqpModel> _versionToModelMap = new HashMap<AmqpVersion, AmqpModel>();
+
+    protected int generatedFileCounter;
+
+    public Generator()
+    {
+        _versionSet = new AmqpVersionSet();
+        _model = new AmqpModel(this);
+        _constantSet = new AmqpConstantSet(this);
+        _domainMap = new AmqpDomainMap(this);
+
+        generatedFileCounter = 0;
+    }
+
+//    public final AmqpVersionSet getVersionSet()
+//    {
+//        return _versionSet;
+//    }
+
+
+    public void addVersion(AmqpVersion version)
+    {
+        _versionSet.add(version);
+        if (!_versionToModelMap.containsKey(version))
+        {
+            _versionToModelMap.put(version, new AmqpModel(this));
+        }
+        if (!_versionToDomainMapMap.containsKey(version))
+        {
+            _versionToDomainMapMap.put(version, new AmqpDomainMap(this));
+        }
+        if (!_versionToConstantSetMap.containsKey(version))
+        {
+            _versionToConstantSetMap.put(version, new AmqpConstantSet(this));
+        }
+    }
+
+    public int getNumberGeneratedFiles()
+    {
+        return generatedFileCounter;
+    }
+
+//	public AmqpDomainMap getDomainMap()
+//	{
+//		return _domainMap;
+//	}
+//
+//    public AmqpConstantSet getConstantSet()
+//    {
+//        return _constantSet;
+//    }
+//
+//
+//	public AmqpModel getModel()
+//	{
+//		return _model;
+//	}
+
+    public void initializeTemplates() throws IOException
+    {
+
+        for (TemplateType type : EnumSet.allOf(TemplateType.class))
+        {
+            ArrayList<NamedTemplate> typeTemplates = new ArrayList<NamedTemplate>();
+            _templates.put(type, typeTemplates);
+            ArrayList<NamedTemplate> versionSpecificTypeTemplates = new ArrayList<NamedTemplate>();
+            _versionSpecificTemplates.put(type, versionSpecificTypeTemplates);
+
+            File templateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName());
+            File versionTemplateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName() + Utils.FILE_SEPARATOR + "version");
+
+            System.out.println("Looking for template files in directory: " + templateDirectory.getAbsoluteFile());
+
+            File[] templateFiles = templateDirectory.listFiles(_tmplFileFilter);
+
+            File[] versionTemplateFiles = new File[0];
+
+            System.out.println("Looking for version specific template files in directory: " + versionTemplateDirectory.getAbsoluteFile());
+
+            if (versionTemplateDirectory.exists())
+            {
+                versionTemplateFiles = versionTemplateDirectory.listFiles(_tmplFileFilter);
+            }
+
+			if(templateFiles != null)
+			{
+	            for (File templateFile : templateFiles)
+	            {
+	                System.out.println(type.getName() + " template file(s):");
+	                System.out.println("  " + templateFile.getCanonicalPath());
+	                typeTemplates.add(new NamedTemplate(type.getName(), templateFile));
+	            }
+			}
+
+            if(versionTemplateFiles != null)
+			{
+				for (File versionTemplateFile : versionTemplateFiles)
+	            {
+	                System.out.println(type.getName() + " template file(s):");
+	                System.out.println("  " + versionTemplateFile.getCanonicalPath());
+	                versionSpecificTypeTemplates.add(new NamedTemplate(type.getName() + Utils.FILE_SEPARATOR + "version", versionTemplateFile));
+	            }
+			}
+
+        }
+    }
+
+    public String getTemplateDirectory()
+    {
+        return _templateDirectory;
+    }
+
+
+    public void setTemplateDirectory(String templateDirectory)
+    {
+        _templateDirectory = templateDirectory;
+    }
+
+
+    public void setOutputDirectory(String outputDirectory)
+    {
+        _outputDirectory = outputDirectory;
+    }
+
+    public void generate()
+    {
+        prepareTargetDirectory(new File(_outputDirectory), true);
+        System.out.println("Generation directory: " + _outputDirectory);
+
+
+        processModelTemplates(_templates);
+
+        for (AmqpClass amqpClass : _model.getClassMap().values())
+        {
+            processClassTemplates(_templates, amqpClass);
+
+            for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values())
+            {
+                processMethodTemplates(_templates, amqpClass, amqpMethod);
+
+                for (AmqpField amqpField : amqpMethod.getFieldMap().values())
+                {
+                    processFieldTemplates(_templates, amqpClass, amqpMethod, amqpField, null);
+                }
+            }
+        }
+
+
+        for (AmqpVersion version : _versionSet)
+        {
+            AmqpModel model = _versionToModelMap.get(version);
+            processModelTemplates(_versionSpecificTemplates, version);
+
+            for (AmqpClass amqpClass : model.getClassMap().values())
+            {
+                processClassTemplates(_versionSpecificTemplates, amqpClass, version);
+
+                for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values())
+                {
+                    processMethodTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, version);
+
+                    for (AmqpField amqpField : amqpMethod.getFieldMap().values())
+                    {
+                        processFieldTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, amqpField, version);
+                    }
+                }
+            }
+
+        }
+    }
+
+    private void processMethodTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version)
+    {
+        for (NamedTemplate template : templates.get(TemplateType.method))
+        {
+            if(isVelocityTemplate(template))
+            {
+                processVelocityTemplate(template,version,amqpClass,amqpMethod,null);
+            }
+            else
+            {
+                processMethodTemplate(template, amqpClass, amqpMethod);
+            }
+        }
+        
+    }
+
+    private void processClassTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpVersion version)
+    {
+        for (NamedTemplate template : templates.get(TemplateType.clazz))
+        {
+            if(isVelocityTemplate(template))
+            {
+                processVelocityTemplate(template,version,amqpClass,null,null);
+            }
+            else
+            {
+                processClassTemplate(template, amqpClass);
+            }
+        }
+
+    }
+
+
+    private void processModelTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpVersion version)
+    {
+        for (NamedTemplate template : templates.get(TemplateType.model))
+        {
+            if (isVelocityTemplate(template))
+            {
+                processModelVelocityTemplate(template, version);
+            }
+            else
+            {
+                processModelTemplate(template, version);
+            }
+        }
+    }
+
+    abstract void processModelTemplate(NamedTemplate template, AmqpVersion version);
+
+
+    protected void processModelTemplates(Map<TemplateType, Collection<NamedTemplate>> templates)
+    {
+        for (NamedTemplate template : templates.get(TemplateType.model))
+        {
+            if (isVelocityTemplate(template))
+            {
+                processModelVelocityTemplate(template, null);
+            }
+            else
+            {
+                processModelTemplate(template);
+            }
+        }
+    }
+
+    private boolean isVelocityTemplate(NamedTemplate template)
+    {
+        return template.getName().endsWith(VELOCITY_TEMPLATE_SUFFIX);
+    }
+
+    private void processModelVelocityTemplate(NamedTemplate template, AmqpVersion version)
+    {
+        processVelocityTemplate(template,version,null,null,null);
+    }
+
+    private void processVelocityTemplate(NamedTemplate template, AmqpVersion version,
+                                              AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField)
+    {
+
+        VelocityContext context = new VelocityContext();
+
+        AmqpModel model = _model;
+        if(version != null)
+        {
+            model = _versionToModelMap.get(version);
+        }
+        context.put("model", model);
+        context.put("generator", GENERATOR_INFO);
+
+        if (version != null)
+        {
+            context.put("version", version);
+        }
+        if(amqpClass != null)
+        {
+            context.put("amqpClass", amqpClass);
+        }
+
+        if(amqpClass != null)
+        {
+            context.put("amqpMethod", amqpMethod);
+        }
+
+
+        StringWriter sw = new StringWriter();
+
+
+        try
+        {
+            Template velocityTemplate = Velocity.getTemplate(template.getName());
+            velocityTemplate.merge(context, sw);
+            String filename = String.valueOf(context.get("filename"));
+
+            File outputFile = new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename);
+            outputFile.getParentFile().mkdirs();
+            FileWriter outputFileWriter = new FileWriter(outputFile);
+
+            outputFileWriter.append(sw.toString());
+            outputFileWriter.close();
+
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+
+
+    }
+
+
+    protected void processClassTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass)
+    {
+        for (NamedTemplate template : templates.get(TemplateType.clazz))
+        {
+            if(isVelocityTemplate(template))
+            {
+                processVelocityTemplate(template,null,amqpClass,null,null);
+            }
+            else
+            {
+                processClassTemplate(template, amqpClass);
+            }
+        }
+    }
+
+    protected void processMethodTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod)
+    {
+        for (NamedTemplate template : templates.get(TemplateType.method))
+        {
+            if(isVelocityTemplate(template))
+            {
+                processVelocityTemplate(template,null,amqpClass,amqpMethod,null);
+            }
+            else
+            {
+                processMethodTemplate(template, amqpClass, amqpMethod);
+            }
+        }
+    }
+
+
+    protected void processFieldTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion amqpVersion)
+    {
+        for (NamedTemplate template : templates.get(TemplateType.field))
+        {
+            if(isVelocityTemplate(template))
+            {
+                processVelocityTemplate(template,amqpVersion,amqpClass,amqpMethod,amqpField);
+            }
+            else
+            {
+                processTemplate(template, amqpClass, amqpMethod, amqpField, amqpVersion);
+            }
+        }
+    }
+
+
+    protected void processVersionList(StringBuffer sb, int tokStart, int tokEnd)
+    {
+        int lend = sb.indexOf(Utils.LINE_SEPARATOR, tokStart) + 1; // Include cr at end of line
+        String tline = sb.substring(tokEnd, lend); // Line excluding line marker, including cr
+        sb.delete(tokStart, lend);
+
+        for (AmqpVersion v : _versionSet)
+        {
+            // Insert copy of target line
+            StringBuffer isb = new StringBuffer(tline);
+            if (isb.indexOf("${protocol-version-list-entry}") >= 0)
+            {
+                String versionListEntry = "       { ${major}, ${minor} }" +
+                                          (v.equals(_versionSet.last()) ? "" : ",");
+                replaceToken(isb, "${protocol-version-list-entry}", String.valueOf(versionListEntry));
+            }
+            if (isb.indexOf("${major}") >= 0)
+            {
+                replaceToken(isb, "${major}", String.valueOf(v.getMajor()));
+            }
+            if (isb.indexOf("${minor}") >= 0)
+            {
+                replaceToken(isb, "${minor}", String.valueOf(v.getMinor()));
+            }
+            sb.insert(tokStart, isb.toString());
+            tokStart += isb.length();
+        }
+    }
+
+    // Helper functions common to all generators
+
+    protected static void prepareTargetDirectory(File dir, boolean createFlag)
+    {
+        if (dir.exists())
+        {
+            if (!dir.isDirectory())
+            {
+                throw new TargetDirectoryException("\"" + dir.getAbsolutePath() +
+                                                   "\" exists, but is not a directory.");
+            }
+        }
+        else if (createFlag) // Create dir
+        {
+            if (!dir.mkdirs())
+            {
+                throw new TargetDirectoryException("Unable to create directory \"" +
+                                                   dir.getAbsolutePath() + "\".");
+            }
+        }
+        else
+        {
+            throw new TargetDirectoryException("Directory \"" + dir.getAbsolutePath() +
+                                               "\" not found.");
+        }
+
+    }
+
+    protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpVersion version)
+    {
+        AmqpModel model = (version == null) ? _model : _versionToModelMap.get(version);
+
+
+        int lstart = sb.indexOf("%{");
+        while (lstart != -1)
+        {
+            int lend = sb.indexOf("}", lstart + 2);
+            if (lend > 0)
+            {
+                String listToken = sb.substring(lstart + 2, lend);
+                if (listToken.compareTo("VLIST") == 0)
+                {
+                    processVersionList(sb, lstart, lend + 1);
+                }
+                else if (listToken.compareTo("CLIST") == 0)
+                {
+                    processClassList(sb, lstart, lend + 1, model, version);
+                }
+                else if (listToken.compareTo("MLIST") == 0)
+                {
+                    processMethodList(sb, lstart, lend + 1, thisClass);
+                }
+                else if (listToken.compareTo("FLIST") == 0)
+                {
+                    // Pass the FieldMap from either a class or a method.
+                    // If this is called from a class-level template, we assume that the
+                    // class field list is required. In this case, method will be null.
+                    processFieldList(sb, lstart, lend + 1,
+                                     (method == null ? thisClass.getFieldMap() : method.getFieldMap()),
+                                     version);
+                }
+                else if (listToken.compareTo("TLIST") == 0)
+                {
+                    processConstantList(sb, lstart, lend + 1, _constantSet);
+                }
+                else
+                {
+                    throw new AmqpTemplateException("Unknown list token \"%{" + listToken +
+                                                    "}\" found in template at index " + lstart + ".");
+                }
+            }
+            lstart = sb.indexOf("%{", lstart + 1);
+        }
+    }
+
+    protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field,
+                                    AmqpVersion version)
+    {
+        int lstart = sb.indexOf("${");
+        while (lstart != -1)
+        {
+            int lend = sb.indexOf("}", lstart + 2);
+            if (lend > 0)
+            {
+                String token = sb.substring(lstart, lend + 1);
+                replaceToken(sb, lstart, token, processToken(token, thisClass, method, field, version));
+            }
+            lstart = sb.indexOf("${", lstart);
+        }
+    }
+
+    protected static void writeTargetFile(StringBuffer sb, File f)
+    {
+        try
+        {
+            f.getParentFile().mkdirs();
+            FileWriter fw = new FileWriter(f);
+            fw.write(sb.toString().toCharArray());
+            fw.flush();
+            fw.close();
+        }
+        catch (IOException e)
+        {
+            throw new AmqpTemplateException(e.getMessage());
+        }
+    }
+
+
+    protected static String getTemplateFileName(StringBuffer sb)
+    {
+        if (sb.charAt(0) != '&')
+        {
+            throw new AmqpTemplateException("No filename marker &{filename} found at start of template.");
+        }
+        int cr = sb.indexOf(Utils.LINE_SEPARATOR);
+        if (cr < 0)
+        {
+            throw new AmqpTemplateException("Bad template structure - unable to find first line.");
+        }
+        String fileName = sb.substring(2, cr - 1);
+        sb.delete(0, cr + 1);
+        return fileName;
+    }
+
+    protected static void replaceToken(StringBuffer sb, String token, String replacement)
+    {
+        replaceToken(sb, 0, token, replacement);
+    }
+
+    protected static void replaceToken(StringBuffer sb, int index, String token, String replacement)
+    {
+        if (replacement != null)
+        {
+            int start = sb.indexOf(token, index);
+            if (start != -1)
+            {
+                int len = token.length();
+                // Find first letter in token and determine if it is capitalized
+                char firstTokenLetter = getFirstLetter(token);
+                if (firstTokenLetter != 0 && Character.isUpperCase(firstTokenLetter))
+                {
+                    sb.replace(start, start + len, Utils.firstUpper(replacement));
+                }
+                else
+                {
+                    sb.replace(start, start + len, replacement);
+                }
+            }
+        }
+    }
+
+    private static char getFirstLetter(String str)
+    {
+        int len = str.length();
+        int index = 0;
+        char tokChar = str.charAt(index);
+        while (!Character.isLetter(tokChar) && index < len - 1)
+        {
+            tokChar = str.charAt(++index);
+        }
+        if (Character.isLetter(tokChar))
+        {
+            return tokChar;
+        }
+        return 0;
+    }
+
+    private static String loadTemplate(File f)
+    {
+        try
+        {
+            StringBuffer sb = new StringBuffer();
+            FileReader fr = new FileReader(f);
+            LineNumberReader lnr = new LineNumberReader(fr);
+            String line = lnr.readLine();
+            while (line != null)
+            {
+
+                sb.append(line);
+                sb.append(Utils.LINE_SEPARATOR);
+
+                line = lnr.readLine();
+            }
+            lnr.close();
+            fr.close();
+            return sb.toString();
+        }
+        catch (FileNotFoundException e)
+        {
+            throw new AmqpTemplateException("File not found: " + e.getMessage());
+        }
+        catch (IOException e)
+        {
+            throw new AmqpTemplateException("IOException: " + e.getMessage());
+        }
+    }
+
+    public String getDomainType(String domainName, AmqpVersion version)
+    {
+        if (version == null)
+        {
+            version = _versionSet.first();
+        }
+        return getDomainMap().getDomainType(domainName, version);
+    }
+
+
+    public void addFromNode(Node amqpNode, AmqpVersion version)
+    {
+        // 1c. Extract domains
+        getConstantSet().addFromNode(amqpNode, 0, version);
+        _versionToConstantSetMap.get(version).addFromNode(amqpNode, 0, version);
+
+        // 1d. Extract domains
+        getDomainMap().addFromNode(amqpNode, 0, version);
+        _versionToDomainMapMap.get(version).addFromNode(amqpNode, 0, version);
+
+        // 1e. Extract class/method/field heirarchy
+        getModel().addFromNode(amqpNode, 0, version);
+        _versionToModelMap.get(version).addFromNode(amqpNode, 0, version);
+    }
+
+
+    public String getOutputDirectory()
+    {
+        return _outputDirectory;
+    }
+
+    public String prepareConstantName(String constantName)
+    {
+        return prepareDomainName(constantName);
+    }
+
+
+    public boolean isFixedSizeType(String type)
+    {
+        return FIXED_SIZE_TYPES.containsKey(type);
+    }
+
+
+    public int getTypeSize(String type)
+    {
+        return FIXED_SIZE_TYPES.get(type);
+    }
+
+
+
+    // Model-level template processing
+    abstract protected void processModelTemplate(NamedTemplate template);
+
+    // Class-level template processing
+    abstract protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass);
+
+    // Method-level template processing
+    abstract protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass,
+                                                  AmqpMethod method);
+
+    // Field-level template processing
+    abstract protected void processTemplate(NamedTemplate template, AmqpClass thisClass,
+                                            AmqpMethod method, AmqpField field, AmqpVersion version);
+
+    abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method,
+                                              AmqpField field, AmqpVersion version);
+
+    abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method,
+                                           AmqpField field, AmqpVersion version);
+
+    abstract protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+                                             AmqpModel model, AmqpVersion version);
+
+    abstract protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+                                              AmqpClass thisClass);
+
+
+    abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+                                             AmqpFieldMap fieldMap, AmqpVersion version);
+
+    abstract protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+                                                AmqpConstantSet constantSet);
+
+
+}

Modified: incubator/qpid/trunk/qpid/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java (original)
+++ incubator/qpid/trunk/qpid/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java Wed Apr 23 18:54:20 2008
@@ -140,5 +140,15 @@
     }
 
 
+    public boolean isServerMethod()
+    {
+        return _amqpMethod.isServerMethod(_amqpVersion);
+    }
+
+
+    public boolean isClientMethod()
+    {
+        return _amqpMethod.isClientMethod(_amqpVersion);        
+    }
 
 }

Modified: incubator/qpid/trunk/qpid/java/broker/pom.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/pom.xml?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/pom.xml (original)
+++ incubator/qpid/trunk/qpid/java/broker/pom.xml Wed Apr 23 18:54:20 2008
@@ -22,14 +22,14 @@
     <groupId>org.apache.qpid</groupId>
     <artifactId>qpid-broker</artifactId>
     <packaging>jar</packaging>
-    <version>1.0-incubating-M2.1-SNAPSHOT</version>
+    <version>1.0-incubating-M3-SNAPSHOT</version>
     <name>Qpid Broker</name>
     <url>http://cwiki.apache.org/confluence/display/qpid</url>
 
     <parent>
         <groupId>org.apache.qpid</groupId>
         <artifactId>qpid</artifactId>
-        <version>1.0-incubating-M2.1-SNAPSHOT</version>
+        <version>1.0-incubating-M3-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/grammar/SelectorParser.jj
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/grammar/SelectorParser.jj?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/grammar/SelectorParser.jj (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/grammar/SelectorParser.jj Wed Apr 23 18:54:20 2008
@@ -94,7 +94,7 @@
             return this.JmsSelector();
         }
         catch (Throwable e) {
-	        throw (AMQInvalidArgumentException)new AMQInvalidArgumentException(sql).initCause(e);
+	        throw (AMQInvalidArgumentException)new AMQInvalidArgumentException(sql, e);
         }
 
     }

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java Wed Apr 23 18:54:20 2008
@@ -67,7 +67,7 @@
         if (exchType == null)
         {
 
-            throw new AMQUnknownExchangeType("Unknown exchange type: " + type);
+            throw new AMQUnknownExchangeType("Unknown exchange type: " + type, null);
         }
         Exchange e = exchType.newInstance(_host, exchange, durable, ticket, autoDelete);
         return e;

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java Wed Apr 23 18:54:20 2008
@@ -101,7 +101,7 @@
             else if (!exchange.getType().equals(body.getType()))
             {
 
-                throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + body.getExchange() + " of type " + exchange.getType() + " to " + body.getType() +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor());
+                throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + body.getExchange() + " of type " + exchange.getType() + " to " + body.getType() +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor(), null);
             }
 
         }

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java Wed Apr 23 18:54:20 2008
@@ -37,9 +37,9 @@
 
     public AccessResult authorise(AMQProtocolSession session, Permission permission, AMQMethodBody body, Object... parameters)
     {
-        if (_logger.isDebugEnabled())
+        if (ACLManager.getLogger().isDebugEnabled())
         {
-            _logger.debug("Allowing user:" + session.getAuthorizedID() + " for :" + permission.toString()
+            ACLManager.getLogger().debug("Allowing user:" + session.getAuthorizedID() + " for :" + permission.toString()
                                         + " on " + body.getClass().getSimpleName()
                                         + (parameters == null || parameters.length == 0 ? "" : "-" + accessablesToString(parameters)));
         }

Modified: incubator/qpid/trunk/qpid/java/client/build.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/build.xml?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/build.xml (original)
+++ incubator/qpid/trunk/qpid/java/client/build.xml Wed Apr 23 18:54:20 2008
@@ -21,7 +21,7 @@
 <project name="AMQ Client" default="build">
 
   <property name="module.depends" value="common"/>
-  <property name="module.test.depends" value="broker"/>
+  <property name="module.test.depends" value="broker junit-toolkit"/>
 
   <import file="../module.xml"/>
 
@@ -29,9 +29,9 @@
 
   <target name="precompile">
     <mkdir dir="${output.dir}"/>
-    <exec executable="javacc">
-      <arg line="-OUTPUT_DIRECTORY=${output.dir} src/main/grammar/SelectorParser.jj"/>
-    </exec>
+    <javacc target="src/main/grammar/SelectorParser.jj"
+            outputdirectory="${output.dir}"
+            javacchome="${project.root}/lib"/>
   </target>
 
 </project>

Added: incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java?rev=651133&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java (added)
+++ incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java Wed Apr 23 18:54:20 2008
@@ -0,0 +1,171 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.example.transport;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.jms.ConnectionListener;
+import org.apache.qpid.url.URLSyntaxException;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.channels.SocketChannel;
+import java.util.UUID;
+
+/**
+ * This is a simple application that demonstrates how you can use the Qpid AMQP interfaces to use existing sockets as
+ * the transport for the Client API.
+ *
+ * The Demo here runs twice:
+ * 1. Just to show a simple publish and receive.
+ * 2. To demonstrate how to use existing sockets and utilise the underlying client failover mechnaism.
+ */
+public class ExistingSocketConnectorDemo implements ConnectionListener
+{
+    private static boolean DEMO_FAILOVER = false;
+
+    public static void main(String[] args) throws IOException, URLSyntaxException, AMQException, JMSException
+    {
+        System.out.println("Testing socket connection to localhost:5672.");
+
+        new ExistingSocketConnectorDemo();
+
+        System.out.println("Testing socket connection failover between localhost:5672 and localhost:5673.");
+
+        DEMO_FAILOVER = true;
+
+        new ExistingSocketConnectorDemo();
+    }
+
+    Connection _connection;
+    MessageProducer _producer;
+    Session _session;
+
+    String Socket1_ID = UUID.randomUUID().toString();
+    String Socket2_ID = UUID.randomUUID().toString();
+
+
+
+    /** Here we can see the broker we are connecting to is set to be 'socket:///' signifying we will provide the socket. */
+    public final String CONNECTION = "amqp://guest:guest@id/test?brokerlist='socket://" + Socket1_ID + ";socket://" + Socket2_ID + "'";
+
+
+    public ExistingSocketConnectorDemo() throws IOException, URLSyntaxException, AMQException, JMSException
+    {
+
+        Socket socket = SocketChannel.open().socket();
+        socket.connect(new InetSocketAddress("localhost", 5672));
+
+        TransportConnection.registerOpenSocket(Socket1_ID, socket);
+
+
+        _connection = new AMQConnection(CONNECTION);
+
+        _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+        MessageConsumer consumer = _session.createConsumer(_session.createQueue("Queue"));
+
+        _producer = _session.createProducer(_session.createQueue("Queue"));
+
+        _connection.start();
+
+        if (!DEMO_FAILOVER)
+        {
+            _producer.send(_session.createTextMessage("Simple Test"));
+        }
+        else
+        {
+            // Using the Qpid interfaces we can set a listener that allows us to demonstrate failover
+            ((AMQConnection) _connection).setConnectionListener(this);
+
+            System.out.println("Testing failover: Please ensure second broker running on localhost:5673 and shutdown broker on 5672.");
+        }
+
+        //We do a blocking receive here so that we can demonstrate failover.
+        Message message = consumer.receive();
+
+        System.out.println("Recevied :" + message);
+
+        _connection.close();
+    }
+
+    // ConnectionListener Interface
+
+    public void bytesSent(long count)
+    {
+        //not used in this example
+    }
+    public void bytesReceived(long count)
+    {
+        //not used in this example
+    }
+
+    public boolean preFailover(boolean redirect)
+    {
+        /**
+         * This method is called before the underlying client library starts to reconnect. This gives us the opportunity
+         * to set a new socket for the failover to occur on.
+         */
+        try
+        {
+            Socket socket = SocketChannel.open().socket();
+
+            socket.connect(new InetSocketAddress("localhost", 5673));
+
+            // This is the new method to pass in an open socket for the connection to use.
+            TransportConnection.registerOpenSocket(Socket2_ID, socket);
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
+
+    public boolean preResubscribe()
+    {
+        //not used in this example - but must return true to allow the resubscription of existing clients.
+        return true;
+    }
+
+    public void failoverComplete()
+    {
+        // Now that failover has completed we can send a message that the receiving thread will pick up
+        try
+        {
+            _producer.send(_session.createTextMessage("Simple Failover Test"));
+        }
+        catch (JMSException e)
+        {
+            e.printStackTrace();
+        }
+    }
+}

Modified: incubator/qpid/trunk/qpid/java/client/pom.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/pom.xml?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/pom.xml (original)
+++ incubator/qpid/trunk/qpid/java/client/pom.xml Wed Apr 23 18:54:20 2008
@@ -69,18 +69,8 @@
             <artifactId>commons-lang</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>org.apache.mina</groupId>
-            <artifactId>mina-filter-ssl</artifactId>
-        </dependency>
 
         <!-- Test Dependencies -->
-        <dependency>  
-            <groupId>org.slf4j</groupId> 
-            <artifactId>slf4j-log4j12</artifactId>  
-            <version>1.4.0</version>  
-            <scope>test</scope> 
-        </dependency>
 
         <dependency> <!-- for inVm Broker -->
             <groupId>org.apache.qpid</groupId>
@@ -89,19 +79,7 @@
         </dependency>
 
         <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.easymock</groupId>
-            <artifactId>easymockclassextension</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>uk.co.thebadgerset</groupId>
+            <groupId>org.apache.qpid</groupId>
             <artifactId>junit-toolkit</artifactId>
             <scope>test</scope>
         </dependency>

Modified: incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj?rev=651133&r1=651132&r2=651133&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj (original)
+++ incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj Wed Apr 23 18:54:20 2008
@@ -170,6 +170,8 @@
 TOKEN [IGNORE_CASE] :
 {
     < ID : ["a"-"z", "_", "$"] (["a"-"z","0"-"9","_", "$"])* >
+    | < QUOTED_ID : "\"" ( ("\"\"") | ~["\""] )*  "\""  >
+
 }
 
 // ----------------------------------------------------------------------------
@@ -577,6 +579,7 @@
 PropertyExpression variable() :
 {
     Token t;
+    StringBuffer rc = new StringBuffer();
     PropertyExpression left=null;
 }
 {
@@ -585,6 +588,20 @@
         {
             left = new PropertyExpression(t.image);
         }
+        |
+        t = <QUOTED_ID>
+        {
+            // Decode the sting value.
+            String image = t.image;
+            for( int i=1; i < image.length()-1; i++ ) {
+                char c = image.charAt(i);
+                if( c == '"' )
+                    i++;
+                rc.append(c);
+            }
+            return new PropertyExpression(rc.toString());
+        }
+
     )
     {
         return left;

Added: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java?rev=651133&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java Wed Apr 23 18:54:20 2008
@@ -0,0 +1,478 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.transport.socket.nio;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoConnectorConfig;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.support.BaseIoConnector;
+import org.apache.mina.common.support.DefaultConnectFuture;
+import org.apache.mina.util.NamePreservingRunnable;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.Queue;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * {@link IoConnector} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 627427 $, $Date: 2008-02-13 14:39:10 +0000 (Wed, 13 Feb 2008) $
+ */
+public class ExistingSocketConnector extends BaseIoConnector
+{
+    /** @noinspection StaticNonFinalField */
+    private static volatile int nextId = 0;
+
+    private final Object lock = new Object();
+    private final int id = nextId++;
+    private final String threadName = "SocketConnector-" + id;
+    private SocketConnectorConfig defaultConfig = new SocketConnectorConfig();
+    private final Queue connectQueue = new Queue();
+    private final SocketIoProcessor[] ioProcessors;
+    private final int processorCount;
+    private final Executor executor;
+
+    /** @noinspection FieldAccessedSynchronizedAndUnsynchronized */
+    private Selector selector;
+    private Worker worker;
+    private int processorDistributor = 0;
+    private int workerTimeout = 60;  // 1 min.
+    private Socket _openSocket = null;
+
+    /** Create a connector with a single processing thread using a NewThreadExecutor */
+    public ExistingSocketConnector()
+    {
+        this(1, new NewThreadExecutor());
+    }
+
+    /**
+     * Create a connector with the desired number of processing threads
+     *
+     * @param processorCount Number of processing threads
+     * @param executor       Executor to use for launching threads
+     */
+    public ExistingSocketConnector(int processorCount, Executor executor)
+    {
+        if (processorCount < 1)
+        {
+            throw new IllegalArgumentException("Must have at least one processor");
+        }
+
+        this.executor = executor;
+        this.processorCount = processorCount;
+        ioProcessors = new SocketIoProcessor[processorCount];
+
+        for (int i = 0; i < processorCount; i++)
+        {
+            ioProcessors[i] = new SocketIoProcessor("SocketConnectorIoProcessor-" + id + "." + i, executor);
+        }
+    }
+
+    /**
+     * How many seconds to keep the connection thread alive between connection requests
+     *
+     * @return Number of seconds to keep connection thread alive
+     */
+    public int getWorkerTimeout()
+    {
+        return workerTimeout;
+    }
+
+    /**
+     * Set how many seconds the connection worker thread should remain alive once idle before terminating itself.
+     *
+     * @param workerTimeout Number of seconds to keep thread alive. Must be >=0
+     */
+    public void setWorkerTimeout(int workerTimeout)
+    {
+        if (workerTimeout < 0)
+        {
+            throw new IllegalArgumentException("Must be >= 0");
+        }
+        this.workerTimeout = workerTimeout;
+    }
+
+    public ConnectFuture connect(SocketAddress address, IoHandler handler, IoServiceConfig config)
+    {
+        return connect(address, null, handler, config);
+    }
+
+    public ConnectFuture connect(SocketAddress address, SocketAddress localAddress,
+                                 IoHandler handler, IoServiceConfig config)
+    {
+        /** Changes here from the Mina OpenSocketConnector.
+         * Ignoreing all address as they are not needed */
+
+        if (handler == null)
+        {
+            throw new NullPointerException("handler");
+        }
+
+
+        if (config == null)
+        {
+            config = getDefaultConfig();
+        }
+
+        if (_openSocket == null)
+        {
+            throw new IllegalArgumentException("Specifed Socket not active");
+        }
+
+        boolean success = false;
+
+        try
+        {
+            DefaultConnectFuture future = new DefaultConnectFuture();
+            newSession(_openSocket, handler, config, future);
+            success = true;
+            return future;
+        }
+        catch (IOException e)
+        {
+            return DefaultConnectFuture.newFailedFuture(e);
+        }
+        finally
+        {
+            if (!success && _openSocket != null)
+            {
+                try
+                {
+                    _openSocket.close();
+                }
+                catch (IOException e)
+                {
+                    ExceptionMonitor.getInstance().exceptionCaught(e);
+                }
+            }
+        }
+    }
+
+    public IoServiceConfig getDefaultConfig()
+    {
+        return defaultConfig;
+    }
+
+    /**
+     * Sets the config this connector will use by default.
+     *
+     * @param defaultConfig the default config.
+     *
+     * @throws NullPointerException if the specified value is <code>null</code>.
+     */
+    public void setDefaultConfig(SocketConnectorConfig defaultConfig)
+    {
+        if (defaultConfig == null)
+        {
+            throw new NullPointerException("defaultConfig");
+        }
+        this.defaultConfig = defaultConfig;
+    }
+
+    private synchronized void startupWorker() throws IOException
+    {
+        if (worker == null)
+        {
+            selector = Selector.open();
+            worker = new Worker();
+            executor.execute(new NamePreservingRunnable(worker));
+        }
+    }
+
+    private void registerNew()
+    {
+        if (connectQueue.isEmpty())
+        {
+            return;
+        }
+
+        for (; ;)
+        {
+            ConnectionRequest req;
+            synchronized (connectQueue)
+            {
+                req = (ConnectionRequest) connectQueue.pop();
+            }
+
+            if (req == null)
+            {
+                break;
+            }
+
+            SocketChannel ch = req.channel;
+            try
+            {
+                ch.register(selector, SelectionKey.OP_CONNECT, req);
+            }
+            catch (IOException e)
+            {
+                req.setException(e);
+            }
+        }
+    }
+
+    private void processSessions(Set keys)
+    {
+        Iterator it = keys.iterator();
+
+        while (it.hasNext())
+        {
+            SelectionKey key = (SelectionKey) it.next();
+
+            if (!key.isConnectable())
+            {
+                continue;
+            }
+
+            SocketChannel ch = (SocketChannel) key.channel();
+            ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+            boolean success = false;
+            try
+            {
+                ch.finishConnect();
+                newSession(ch, entry.handler, entry.config, entry);
+                success = true;
+            }
+            catch (Throwable e)
+            {
+                entry.setException(e);
+            }
+            finally
+            {
+                key.cancel();
+                if (!success)
+                {
+                    try
+                    {
+                        ch.close();
+                    }
+                    catch (IOException e)
+                    {
+                        ExceptionMonitor.getInstance().exceptionCaught(e);
+                    }
+                }
+            }
+        }
+
+        keys.clear();
+    }
+
+    private void processTimedOutSessions(Set keys)
+    {
+        long currentTime = System.currentTimeMillis();
+        Iterator it = keys.iterator();
+
+        while (it.hasNext())
+        {
+            SelectionKey key = (SelectionKey) it.next();
+
+            if (!key.isValid())
+            {
+                continue;
+            }
+
+            ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+            if (currentTime >= entry.deadline)
+            {
+                entry.setException(new ConnectException());
+                try
+                {
+                    key.channel().close();
+                }
+                catch (IOException e)
+                {
+                    ExceptionMonitor.getInstance().exceptionCaught(e);
+                }
+                finally
+                {
+                    key.cancel();
+                }
+            }
+        }
+    }
+
+    private void newSession(Socket socket, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+            throws IOException
+    {
+        SocketSessionImpl session = new SocketSessionImpl(this,
+                                                          nextProcessor(),
+                                                          getListeners(),
+                                                          config,
+                                                          socket.getChannel(),
+                                                          handler,
+                                                          socket.getRemoteSocketAddress());
+
+        newSession(session, config, connectFuture);
+    }
+
+    private void newSession(SocketChannel ch, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+            throws IOException
+
+    {
+        SocketSessionImpl session = new SocketSessionImpl(this,
+                                                          nextProcessor(),
+                                                          getListeners(),
+                                                          config,
+                                                          ch,
+                                                          handler,
+                                                          ch.socket().getRemoteSocketAddress());
+
+        newSession(session, config, connectFuture);
+    }
+
+    private void newSession(SocketSessionImpl session, IoServiceConfig config, ConnectFuture connectFuture)
+            throws IOException
+    {
+        try
+        {
+            getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+            config.getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+            config.getThreadModel().buildFilterChain(session.getFilterChain());
+        }
+        catch (Throwable e)
+        {
+            throw (IOException) new IOException("Failed to create a session.").initCause(e);
+        }
+        session.getIoProcessor().addNew(session);
+        connectFuture.setSession(session);
+    }
+
+    private SocketIoProcessor nextProcessor()
+    {
+        return ioProcessors[processorDistributor++ % processorCount];
+    }
+
+    public void setOpenSocket(Socket openSocket)
+    {
+        _openSocket = openSocket;
+    }
+
+    private class Worker implements Runnable
+    {
+        private long lastActive = System.currentTimeMillis();
+
+        public void run()
+        {
+            Thread.currentThread().setName(ExistingSocketConnector.this.threadName);
+
+            for (; ;)
+            {
+                try
+                {
+                    int nKeys = selector.select(1000);
+
+                    registerNew();
+
+                    if (nKeys > 0)
+                    {
+                        processSessions(selector.selectedKeys());
+                    }
+
+                    processTimedOutSessions(selector.keys());
+
+                    if (selector.keys().isEmpty())
+                    {
+                        if (System.currentTimeMillis() - lastActive > workerTimeout * 1000L)
+                        {
+                            synchronized (lock)
+                            {
+                                if (selector.keys().isEmpty() &&
+                                    connectQueue.isEmpty())
+                                {
+                                    worker = null;
+                                    try
+                                    {
+                                        selector.close();
+                                    }
+                                    catch (IOException e)
+                                    {
+                                        ExceptionMonitor.getInstance().exceptionCaught(e);
+                                    }
+                                    finally
+                                    {
+                                        selector = null;
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    else
+                    {
+                        lastActive = System.currentTimeMillis();
+                    }
+                }
+                catch (IOException e)
+                {
+                    ExceptionMonitor.getInstance().exceptionCaught(e);
+
+                    try
+                    {
+                        Thread.sleep(1000);
+                    }
+                    catch (InterruptedException e1)
+                    {
+                        ExceptionMonitor.getInstance().exceptionCaught(e1);
+                    }
+                }
+            }
+        }
+    }
+
+    private class ConnectionRequest extends DefaultConnectFuture
+    {
+        private final SocketChannel channel;
+        private final long deadline;
+        private final IoHandler handler;
+        private final IoServiceConfig config;
+
+        private ConnectionRequest(SocketChannel channel, IoHandler handler, IoServiceConfig config)
+        {
+            this.channel = channel;
+            long timeout;
+            if (config instanceof IoConnectorConfig)
+            {
+                timeout = ((IoConnectorConfig) config).getConnectTimeoutMillis();
+            }
+            else
+            {
+                timeout = ((IoConnectorConfig) getDefaultConfig()).getConnectTimeoutMillis();
+            }
+            this.deadline = System.currentTimeMillis() + timeout;
+            this.handler = handler;
+            this.config = config;
+        }
+    }
+}



Mime
View raw message