blob: 9fc81dd428405188141a70a874d37317ce56a43d [file] [log] [blame]
/*
*
* 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 java.io.File;
import java.util.TreeMap;
public class DotnetGenerator extends Generator
{
private class DomainInfo
{
public String type;
public String size;
public String encodeExpression;
public String decodeExpression;
public DomainInfo(String domain, String size, String encodeExpression, String decodeExpression)
{
this.type = domain;
this.size = size;
this.encodeExpression = encodeExpression;
this.decodeExpression = decodeExpression;
}
}
private static TreeMap<String, DomainInfo> typeMap = new TreeMap<String, DomainInfo>();
public String getNativeType(String type)
{
throw new UnsupportedOperationException();
}
public String getEncodingType(String type)
{
throw new UnsupportedOperationException();
}
public DotnetGenerator()
{
super();
// Load .NET type and size maps.
// Adjust or add to these lists as new types are added/defined.
// The char '#' will be replaced by the field variable name (any type).
// The char '~' will be replaced by the compacted bit array size (type bit only).
// TODO: I have left a copy of the Java typeMap here - replace with appropriate .NET values.
typeMap.put("bit", new DomainInfo(
"boolean", // .NET code type
"~", // size
"EncodingUtils.writeBooleans(buffer, #)", // encode expression
"# = EncodingUtils.readBooleans(buffer)")); // decode expression
typeMap.put("content", new DomainInfo(
"Content", // .NET code type
"EncodingUtils.encodedContentLength(#)", // size
"EncodingUtils.writeContentBytes(buffer, #)", // encode expression
"# = EncodingUtils.readContent(buffer)")); // decode expression
typeMap.put("long", new DomainInfo(
"long", // .NET code type
"4", // size
"EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression
"# = buffer.getUnsignedInt()")); // decode expression
typeMap.put("longlong", new DomainInfo(
"long", // .NET code type
"8", // size
"buffer.putLong(#)", // encode expression
"# = buffer.getLong()")); // decode expression
typeMap.put("longstr", new DomainInfo(
"byte[]", // .NET code type
"EncodingUtils.encodedLongstrLength(#)", // size
"EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression
"# = EncodingUtils.readLongstr(buffer)")); // decode expression
typeMap.put("octet", new DomainInfo(
"short", // .NET code type
"1", // size
"EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression
"# = buffer.getUnsigned()")); // decode expression
typeMap.put("short", new DomainInfo(
"int", // .NET code type
"2", // size
"EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression
"# = buffer.getUnsignedShort()")); // decode expression
typeMap.put("shortstr", new DomainInfo(
"AMQShortString", // .NET code type
"EncodingUtils.encodedShortStringLength(#)", // size
"EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression
"# = EncodingUtils.readAMQShortString(buffer)")); // decode expression
typeMap.put("table", new DomainInfo(
"FieldTable", // .NET code type
"EncodingUtils.encodedFieldTableLength(#)", // size
"EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression
"# = EncodingUtils.readFieldTable(buffer)")); // decode expression
typeMap.put("timestamp", new DomainInfo(
"long", // .NET code type
"8", // size
"EncodingUtils.writeTimestamp(buffer, #)", // encode expression
"# = EncodingUtils.readTimestamp(buffer)")); // decode expression
}
void processModelTemplate(NamedTemplate template, AmqpVersion version)
{
//To change body of implemented methods use File | Settings | File Templates.
}
void processClassTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpVersion version)
{
//To change body of implemented methods use File | Settings | File Templates.
}
void processMethodTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version)
{
//To change body of implemented methods use File | Settings | File Templates.
}
void processFieldTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion version)
{
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
protected String prepareFilename(String filenameTemplate,
AmqpClass thisClass, AmqpMethod method, AmqpField field, AmqpVersion version)
{
StringBuffer sb = new StringBuffer(filenameTemplate);
if (thisClass != null)
{
replaceToken(sb, "${CLASS}", thisClass.getName());
}
if (method != null)
{
replaceToken(sb, "${METHOD}", method.getName());
}
if (field != null)
{
replaceToken(sb, "${FIELD}", field.getName());
}
return sb.toString();
}
@Override
protected void processClassList(StringBuffer sb, int listMarkerStartIndex,
int listMarkerEndIndex, AmqpModel model, AmqpVersion version)
throws AmqpTemplateException, AmqpTypeMappingException
{
String codeSnippet;
int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
int tokStart = tline.indexOf('$');
String token = tline.substring(tokStart).trim();
sb.delete(listMarkerStartIndex, lend);
// TODO: Add in tokens and calls to their corresponding generator methods here...
if (token.compareTo("${??????????}") == 0)
{
codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
// codeSnippet = generateRegistry(model, 8, 4);
}
else // Oops!
{
throw new AmqpTemplateException("Template token " + token + " unknown.");
}
sb.insert(listMarkerStartIndex, codeSnippet);
}
@Override
protected void processConstantList(StringBuffer sb,
int listMarkerStartIndex, int listMarkerEndIndex,
AmqpConstantSet constantSet) throws AmqpTemplateException,
AmqpTypeMappingException
{
String codeSnippet;
int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
int tokStart = tline.indexOf('$');
String token = tline.substring(tokStart).trim();
sb.delete(listMarkerStartIndex, lend);
// TODO: Add in tokens and calls to their corresponding generator methods here...
if (token.compareTo("${??????????}") == 0)
{
codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
// codeSnippet = generateConstantGetMethods(constantSet, 4, 4);
}
else // Oops!
{
throw new AmqpTemplateException("Template token " + token + " unknown.");
}
sb.insert(listMarkerStartIndex, codeSnippet);
}
@Override
protected void processFieldList(StringBuffer sb, int listMarkerStartIndex,
int listMarkerEndIndex, AmqpFieldMap fieldMap, AmqpVersion version)
{
String codeSnippet;
int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
int tokStart = tline.indexOf('$');
String token = tline.substring(tokStart).trim();
sb.delete(listMarkerStartIndex, lend);
// TODO: Add in tokens and calls to their corresponding generator methods here...
if (token.compareTo("${??????????}") == 0)
{
codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
// codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod,
// mangledDeclarationGenerateMethod, 4, 4, this);
}
else // Oops!
{
throw new AmqpTemplateException("Template token " + token + " unknown.");
}
sb.insert(listMarkerStartIndex, codeSnippet);
}
@Override
protected void processMethodList(StringBuffer sb, int listMarkerStartIndex,
int listMarkerEndIndex, AmqpClass thisClass)
throws AmqpTemplateException, AmqpTypeMappingException
{
String codeSnippet;
int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
int tokStart = tline.indexOf('$');
String token = tline.substring(tokStart).trim();
sb.delete(listMarkerStartIndex, lend);
// TODO: Add in tokens and calls to their corresponding generator methods here...
if (token.compareTo("${??????????}") == 0)
{
codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
}
else // Oops!
{
throw new AmqpTemplateException("Template token " + token + " unknown.");
}
sb.insert(listMarkerStartIndex, codeSnippet);
}
@Override
protected void processModelTemplate(NamedTemplate template)
{
// I've put in the Java model here - this can be changed if a different pattern is required.
processTemplate(template, null, null, null, null);
}
@Override
protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass)
{
// I've put in the Java model here - this can be changed if a different pattern is required.
processTemplate(template, thisClass, null, null, null);
}
@Override
protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass,
AmqpMethod method)
{
// I've put in the Java model here - this can be changed if a different pattern is required.
processTemplate(template, thisClass, method, null, null);
}
@Override
protected void processTemplate(NamedTemplate template, AmqpClass thisClass,
AmqpMethod method, AmqpField field, AmqpVersion version)
{
// I've put in the Java model here - this can be changed if a different pattern is required.
StringBuffer sb = new StringBuffer(template.getTemplate());
String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version);
try
{
processAllLists(sb, thisClass, method, null);
}
catch (AmqpTemplateException e)
{
System.out.println("WARNING: " + template.getName() + ": " + e.getMessage());
}
try
{
processAllTokens(sb, thisClass, method, field, null);
}
catch (AmqpTemplateException e)
{
System.out.println("WARNING: " + template.getName() + ": " + e.getMessage());
}
writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename));
generatedFileCounter++;
}
@Override
protected String processToken(String token, AmqpClass thisClass,
AmqpMethod method, AmqpField field, AmqpVersion version)
throws AmqpTemplateException, AmqpTypeMappingException
{
// TODO Auto-generated method stub
return null;
}
public String getGeneratedType(String domainName, AmqpVersion version)
throws AmqpTypeMappingException
{
String domainType = getDomainType(domainName, version);
if (domainType == null)
{
throw new AmqpTypeMappingException("Domain type \"" + domainName +
"\" not found in Java typemap.");
}
DomainInfo info = typeMap.get(domainType);
if (info == null)
{
throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\"");
}
return info.type;
}
public String prepareClassName(String className)
{
return camelCaseName(className, true);
}
public String prepareDomainName(String domainName)
{
return camelCaseName(domainName, false);
}
public String prepareMethodName(String methodName)
{
return camelCaseName(methodName, false);
}
private String camelCaseName(String name, boolean upperFirstFlag)
{
StringBuffer ccn = new StringBuffer();
String[] toks = name.split("[-_.\\ ]");
for (int i = 0; i < toks.length; i++)
{
StringBuffer b = new StringBuffer(toks[i]);
if (upperFirstFlag || i > 0)
{
b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0)));
}
ccn.append(b);
}
return ccn.toString();
}
public static Factory<DotnetGenerator> _factoryInstance = new Factory<DotnetGenerator>()
{
public DotnetGenerator newInstance()
{
return new DotnetGenerator();
}
};
public static Factory<DotnetGenerator> getFactory()
{
return _factoryInstance;
}
}