esa.mo.tools.stubgen.GeneratorJava Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of StubGenerator_Java Show documentation
Show all versions of StubGenerator_Java Show documentation
Generates Java APIs for CCSDS MAL service specifications
The newest version!
/* ----------------------------------------------------------------------------
* Copyright (C) 2013 European Space Agency
* European Space Operations Centre
* Darmstadt
* Germany
* ----------------------------------------------------------------------------
* System : CCSDS MO Service Stub Generator
* ----------------------------------------------------------------------------
* Licensed under the European Space Agency Public License, Version 2.0
* You may not use this file except in compliance with the License.
*
* Except as expressly set forth in this License, the Software is provided to
* You on an "as is" basis and without warranties of any kind, including without
* limitation merchantability, fitness for a particular purpose, absence of
* defects or errors, accuracy or non-infringement of intellectual property rights.
*
* See the License for the specific language governing permissions and
* limitations under the License.
* ----------------------------------------------------------------------------
*/
package esa.mo.tools.stubgen;
import esa.mo.tools.stubgen.specification.AttributeTypeDetails;
import esa.mo.tools.stubgen.specification.CompositeField;
import esa.mo.tools.stubgen.specification.NativeTypeDetails;
import esa.mo.tools.stubgen.specification.OperationSummary;
import esa.mo.tools.stubgen.specification.ServiceSummary;
import esa.mo.tools.stubgen.specification.StdStrings;
import esa.mo.tools.stubgen.specification.TypeUtils;
import esa.mo.tools.stubgen.writers.AbstractLanguageWriter;
import esa.mo.tools.stubgen.writers.ClassWriter;
import esa.mo.tools.stubgen.writers.InterfaceWriter;
import esa.mo.tools.stubgen.writers.LanguageWriter;
import esa.mo.tools.stubgen.writers.MethodWriter;
import esa.mo.tools.stubgen.writers.TargetWriter;
import esa.mo.xsd.AreaType;
import esa.mo.xsd.EnumerationType;
import esa.mo.xsd.ServiceType;
import esa.mo.xsd.TypeReference;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Generates stubs and skeletons for CCSDS MO Service specifications for the
* Java language.
*/
public class GeneratorJava extends GeneratorLangs {
/**
* The file extension for Java files.
*/
public static final String JAVA_FILE_EXT = "java";
/**
* The file name for package level comments.
*/
public static final String JAVA_PACKAGE_COMMENT_FILE_NAME = "package-info";
/**
* Constructor.
*
* @param logger The logger to use.
*/
public GeneratorJava(org.apache.maven.plugin.logging.Log logger) {
super(logger, true, true, false, true, false,
new GeneratorConfiguration("org.ccsds.moims.mo.", "structures", "factory", "body", ".", "(Object[]) null",
"MALSendOperation",
"MALSubmitOperation",
"MALRequestOperation",
"MALInvokeOperation",
"MALProgressOperation",
"MALPubSubOperation"));
}
@Override
public String getShortName() {
return "Java";
}
@Override
public String getDescription() {
return "Generates a Java language mapping.";
}
@Override
public void init(String destinationFolderName,
boolean generateStructures,
boolean generateCOM,
Map packageBindings,
Map extraProperties) throws IOException {
super.init(destinationFolderName, generateStructures, generateCOM, packageBindings, extraProperties);
setRequiresDefaultConstructors(Boolean.valueOf(extraProperties.get("java.requiresDefaultConstructors")));
setSupportFullyPolymorphicTypes(Boolean.valueOf(extraProperties.get("java.supportFullyPolymorphicTypes")));
addAttributeType(StdStrings.MAL, StdStrings.BLOB, false, "Blob", "");
addAttributeType(StdStrings.MAL, StdStrings.BOOLEAN, true, "Boolean", "Boolean.FALSE");
addAttributeType(StdStrings.MAL, StdStrings.DOUBLE, true, "Double", "Double.MAX_VALUE");
addAttributeType(StdStrings.MAL, StdStrings.DURATION, false, "Duration", "");
addAttributeType(StdStrings.MAL, StdStrings.FLOAT, true, "Float", "Float.MAX_VALUE");
addAttributeType(StdStrings.MAL, StdStrings.INTEGER, true, "Integer", "Integer.MAX_VALUE");
addAttributeType(StdStrings.MAL, StdStrings.IDENTIFIER, false, "Identifier", "");
addAttributeType(StdStrings.MAL, StdStrings.LONG, true, "Long", "Long.MAX_VALUE");
addAttributeType(StdStrings.MAL, StdStrings.OCTET, true, "Byte", "Byte.MAX_VALUE");
addAttributeType(StdStrings.MAL, StdStrings.SHORT, true, "Short", "Short.MAX_VALUE");
addAttributeType(StdStrings.MAL, StdStrings.UINTEGER, false, "UInteger", "");
addAttributeType(StdStrings.MAL, StdStrings.ULONG, false, "ULong", "");
addAttributeType(StdStrings.MAL, StdStrings.UOCTET, false, "UOctet", "");
addAttributeType(StdStrings.MAL, StdStrings.USHORT, false, "UShort", "");
addAttributeType(StdStrings.MAL, StdStrings.STRING, true, "String", "\"\"");
addAttributeType(StdStrings.MAL, StdStrings.TIME, false, "Time", "");
addAttributeType(StdStrings.MAL, StdStrings.FINETIME, false, "FineTime", "");
addAttributeType(StdStrings.MAL, StdStrings.URI, false, "URI", "");
addNativeType("boolean", new NativeTypeDetails("boolean", false, false, null));
addNativeType("_String", new NativeTypeDetails("String", false, false, null));
addNativeType("byte", new NativeTypeDetails("byte", false, false, null));
addNativeType("short", new NativeTypeDetails("short", false, false, null));
addNativeType("int", new NativeTypeDetails("int", false, false, null));
addNativeType("long", new NativeTypeDetails("long", false, false, null));
addNativeType("_Integer", new NativeTypeDetails("Integer", true, false, null));
addNativeType("Class", new NativeTypeDetails("Class", true, false, null));
addNativeType("Map", new NativeTypeDetails("java.util.Map", true, false, null));
addNativeType("Vector", new NativeTypeDetails("java.util.Vector", true, false, null));
}
@Override
public void createRequiredPublisher(String destinationFolderName, String fqPublisherName, RequiredPublisher publisher) throws IOException {
getLog().info("Creating publisher class " + fqPublisherName);
String publisherName = fqPublisherName.substring(fqPublisherName.lastIndexOf('.') + 1);
ClassWriter file = createClassFile(destinationFolderName, fqPublisherName.replace('.', '/'));
file.addPackageStatement(publisher.area, publisher.service, PROVIDER_FOLDER);
String throwsMALException = createElementType(file, StdStrings.MAL, null, null, StdStrings.MALEXCEPTION);
String throwsInteractionException = createElementType(file, StdStrings.MAL, null, null, StdStrings.MALINTERACTIONEXCEPTION);
String throwsInteractionAndMALException = throwsInteractionException + ", " + throwsMALException;
String throwsExceptions = "java.lang.IllegalArgumentException, " + throwsInteractionAndMALException;
CompositeField publisherSetType = createCompositeElementsDetails(file, false, "publisherSet", TypeUtils.createTypeReference(StdStrings.MAL, PROVIDER_FOLDER, "MALPublisherSet", false), false, true, null);
file.addClassOpenStatement(publisherName, true, false, null, null, "Publisher class for the " + publisher.operation.getName() + " operation.");
file.addClassVariable(false, false, StdStrings.PRIVATE, publisherSetType, false, (String) null);
MethodWriter method = file.addConstructor(StdStrings.PUBLIC, publisherName, createCompositeElementsDetails(file, false, "publisherSet", TypeUtils.createTypeReference(StdStrings.MAL, PROVIDER_FOLDER, "MALPublisherSet", false), false, true, "publisherSet The set of broker connections to use when registering and publishing."), false, null, "Creates an instance of this class using the supplied publisher set.", null);
method.addMethodStatement("this.publisherSet = publisherSet");
method.addMethodCloseStatement();
CompositeField entKeyList = createCompositeElementsDetails(file, false, "entityKeys", TypeUtils.createTypeReference(StdStrings.MAL, null, "EntityKey", true), true, true, "entityKeys The entity keys to use in the method");
CompositeField psListener = createCompositeElementsDetails(file, false, "listener", TypeUtils.createTypeReference(StdStrings.MAL, PROVIDER_FOLDER, "MALPublishInteractionListener", false), false, true, "listener The listener object to use for callback from the publisher");
method = file.addMethodOpenStatement(false, false, StdStrings.PUBLIC, false, true, null, "register", StubUtils.concatenateArguments(entKeyList, psListener), throwsExceptions,
"Registers this provider implementation to the set of broker connections", null, Arrays.asList("java.lang.IllegalArgumentException If any supplied argument is invalid", throwsInteractionException + " if there is a problem during the interaction as defined by the MAL specification.", throwsMALException + " if there is an implementation exception"));
method.addMethodStatement("publisherSet.register(entityKeys, listener)");
method.addMethodCloseStatement();
method = file.addMethodOpenStatement(false, false, StdStrings.PUBLIC, false, true, null, "asyncRegister", StubUtils.concatenateArguments(entKeyList, psListener), throwsExceptions,
"Asynchronously registers this provider implementation to the set of broker connections", null, Arrays.asList("java.lang.IllegalArgumentException If any supplied argument is invalid", throwsInteractionException + " if there is a problem during the interaction as defined by the MAL specification.", throwsMALException + " if there is an implementation exception"));
method.addMethodStatement("publisherSet.asyncRegister(entityKeys, listener)");
method.addMethodCloseStatement();
List argList = new LinkedList();
argList.add(createCompositeElementsDetails(file, true, "updateHeaderList", TypeUtils.createTypeReference(StdStrings.MAL, null, "UpdateHeader", true), true, true, "updateHeaderList The headers of the updates being added"));
argList.addAll(createOperationArguments(getConfig(), file, publisher.operation.getUpdateTypes(), true));
String argNameList = "";
if (1 < argList.size()) {
List strList = new LinkedList();
for (int i = 1; i < argList.size(); i++) {
strList.add(argList.get(i).getFieldName());
}
argNameList = StubUtils.concatenateStringArguments(true, strList.toArray(new String[0]));
}
method = file.addMethodOpenStatement(false, false, StdStrings.PUBLIC, false, true, null, "publish", argList, throwsExceptions,
"Publishes updates to the set of registered broker connections", null, Arrays.asList("java.lang.IllegalArgumentException If any supplied argument is invalid", throwsInteractionException + " if there is a problem during the interaction as defined by the MAL specification.", throwsMALException + " if there is an implementation exception"));
method.addMethodStatement("publisherSet.publish(updateHeaderList" + argNameList + ")");
method.addMethodCloseStatement();
method = file.addMethodOpenStatement(false, false, StdStrings.PUBLIC, false, true, null, "deregister", null, throwsInteractionAndMALException,
"Deregisters this provider implementation from the set of broker connections", null, Arrays.asList(throwsInteractionException + " if there is a problem during the interaction as defined by the MAL specification.", throwsMALException + " if there is an implementation exception"));
method.addMethodStatement("publisherSet.deregister()");
method.addMethodCloseStatement();
method = file.addMethodOpenStatement(false, false, StdStrings.PUBLIC, false, true, null, "asyncDeregister", Arrays.asList(psListener), throwsExceptions,
"Asynchronously deregisters this provider implementation from the set of broker connections", null, Arrays.asList("java.lang.IllegalArgumentException If any supplied argument is invalid", throwsInteractionException + " if there is a problem during the interaction as defined by the MAL specification.", throwsMALException + " if there is an implementation exception"));
method.addMethodStatement("publisherSet.asyncDeregister(listener)");
method.addMethodCloseStatement();
method = file.addMethodOpenStatement(false, false, StdStrings.PUBLIC, false, true, null, "close", null, throwsMALException,
"Closes this publisher", null, Arrays.asList(throwsMALException + " if there is an implementation exception"));
method.addMethodStatement("publisherSet.close()");
method.addMethodCloseStatement();
file.addClassCloseStatement();
file.flush();
}
@Override
protected void createListClass(File folder, AreaType area, ServiceType service, String srcTypeName, boolean isAbstract, Long shortFormPart) throws IOException {
if (isAbstract) {
createAbstractListClass(folder, area, service, srcTypeName);
} else {
createConcreteListClass(folder, area, service, srcTypeName, shortFormPart);
}
}
/**
* Creates a list for an abstract type.
*
* @param folder The base folder to create the list in.
* @param area The Area of the list.
* @param service The service of the list.
* @param srcTypeName The name of the element in the list.
* @throws IOException if there is a problem writing the file.
*/
protected void createAbstractListClass(File folder, AreaType area, ServiceType service, String srcTypeName) throws IOException {
String listName = srcTypeName + "List";
getLog().info("Creating list interface " + listName);
InterfaceWriter file = createInterfaceFile(folder, listName);
file.addPackageStatement(area, service, getConfig().getStructureFolder());
TypeReference typeRef = TypeUtils.createTypeReference(area.getName(), (null == service) ? null : service.getName(), srcTypeName, false);
TypeReference superTypeReference = getCompositeElementSuperType(typeRef);
String fqSrcTypeName = createElementType(file, area, service, srcTypeName);
if (null == superTypeReference) {
superTypeReference = new TypeReference();
superTypeReference.setArea(StdStrings.MAL);
if (isComposite(typeRef)) {
superTypeReference.setName(StdStrings.COMPOSITE);
} else {
superTypeReference.setName(StdStrings.ELEMENT);
}
}
CompositeField listSuperElement = createCompositeElementsDetails(file, false, null, superTypeReference, true, true, "List element.");
file.addInterfaceOpenStatement(listName + "", listSuperElement.getTypeName() + "List", "List class for " + srcTypeName + "." + file.getLineSeparator() + " * @param The type of this list must extend " + srcTypeName);
file.addInterfaceCloseStatement();
file.flush();
}
/**
* Creates a list for an abstract type.
*
* @param folder The base folder to create the list in.
* @param area The Area of the list.
* @param service The service of the list.
* @param srcTypeName The name of the element in the list.
* @param shortFormPart The short form part of the contained element.
* @throws IOException if there is a problem writing the file.
*/
protected void createConcreteListClass(File folder, AreaType area, ServiceType service, String srcTypeName, Long shortFormPart) throws IOException {
String listName = srcTypeName + "List";
TypeReference srcType = new TypeReference();
srcType.setArea(area.getName());
if (null != service) {
srcType.setService(service.getName());
}
srcType.setName(srcTypeName);
getLog().info("Creating list class " + listName);
ClassWriter file = createClassFile(folder, listName);
file.addPackageStatement(area, service, getConfig().getStructureFolder());
CompositeField elementType = createCompositeElementsDetails(file, false, "return", TypeUtils.createTypeReference(StdStrings.MAL, null, StdStrings.ELEMENT, false), true, true, null);
String fqSrcTypeName = createElementType(file, area, service, srcTypeName);
TypeReference superTypeReference = getCompositeElementSuperType(srcType);
if (null == superTypeReference) {
superTypeReference = new TypeReference();
superTypeReference.setArea(StdStrings.MAL);
if (isAttributeType(srcType)) {
superTypeReference.setName(StdStrings.ATTRIBUTE);
} else if (isEnum(srcType)) {
superTypeReference.setName(StdStrings.ENUMERATION);
} else {
superTypeReference.setName(StdStrings.COMPOSITE);
}
}
CompositeField listSuperElement = createCompositeElementsDetails(file, false, null, superTypeReference, true, true, "List element.");
file.addClassOpenStatement(listName, true, false, "java.util.ArrayList<" + fqSrcTypeName + ">", listSuperElement.getTypeName() + "List<" + fqSrcTypeName + ">", "List class for " + srcTypeName + ".");
CompositeField listElement = createCompositeElementsDetails(file, true, null, srcType, true, true, "List element.");
addTypeShortFormDetails(file, area, service, -shortFormPart);
// create blank constructor
file.addConstructorDefault(listName);
// create initial size contructor
MethodWriter method = file.addConstructor(StdStrings.PUBLIC, listName, createCompositeElementsDetails(file, false, "initialCapacity", TypeUtils.createTypeReference(null, null, "int", false), false, false, "initialCapacity the required initial capacity."), true, null, "Constructor that initialises the capacity of the list.", null);
method.addMethodCloseStatement();
method = file.addMethodOpenStatement(true, false, StdStrings.PUBLIC, false, true, elementType, "createElement", null, null, "Creates an instance of this type using the default constructor. It is a generic factory method.", "A new instance of this type with default field values.", null);
method.addMethodStatement("return new " + listName + "()");
method.addMethodCloseStatement();
// create encode method
method = encodeMethodOpen(file);
method.addMethodStatement("org.ccsds.moims.mo.mal.MALListEncoder listEncoder = encoder.createListEncoder(this)");
method.addMethodStatement("for (int i = 0; i < size(); i++)", false);
method.addMethodStatement("{", false);
method.addMethodStatement(" listEncoder.encodeNullable" + listElement.getEncodeCall() + "((" + fqSrcTypeName + ") get(i))");
method.addMethodStatement("}", false);
method.addMethodStatement("listEncoder.close()");
method.addMethodCloseStatement();
// create decode method
method = decodeMethodOpen(file, elementType);
method.addMethodStatement("org.ccsds.moims.mo.mal.MALListDecoder listDecoder = decoder.createListDecoder(this)");
method.addMethodStatement("int decodedSize = listDecoder.size()");
method.addMethodStatement("if (decodedSize > 0)", false);
method.addMethodStatement("{", false);
method.addMethodStatement(" ensureCapacity(decodedSize)");
method.addMethodStatement("}", false);
method.addMethodStatement("while (listDecoder.hasNext())", false);
method.addMethodStatement("{", false);
method.addMethodStatement(" add(" + listElement.getDecodeCast() + "listDecoder.decodeNullable" + listElement.getDecodeCall() + "(" + (listElement.isDecodeNeedsNewCall() ? listElement.getNewCall() : "") + "))");
method.addMethodStatement("}", false);
method.addMethodStatement("return this");
method.addMethodCloseStatement();
addShortFormMethods(file);
file.addClassCloseStatement();
file.flush();
srcType.setList(Boolean.TRUE);
CompositeField listType = createCompositeElementsDetails(file, false, null, srcType, true, true, "List element.");
createFactoryClass(folder, area, service, listName, listType, false, false);
}
@Override
protected void addTypeShortForm(ClassWriter file, long sf) throws IOException {
file.addMultilineComment("Short form for type.");
file.addStatement(" public static final Integer TYPE_SHORT_FORM = Integer.valueOf(" + sf + ");");
}
@Override
protected void addShortForm(ClassWriter file, long sf) throws IOException {
file.addMultilineComment("Absolute short form for type.");
file.addStatement(" public static final Long SHORT_FORM = Long.valueOf(" + sf + "L);");
file.addStatement(" private static final long serialVersionUID = " + sf + "L;");
}
@Override
protected void createAreaFolderComment(File structureFolder, AreaType area) throws IOException {
String cmt = area.getComment();
if (null == cmt) {
cmt = "The " + area.getName() + " area.";
}
createFolderComment(structureFolder, area, null, null, cmt);
}
@Override
protected void createServiceFolderComment(File structureFolder, AreaType area, ServiceType service) throws IOException {
createFolderComment(structureFolder, area, service, null, service.getComment());
}
@Override
protected void createServiceConsumerFolderComment(File structureFolder, AreaType area, ServiceType service) throws IOException {
createFolderComment(structureFolder, area, service, CONSUMER_FOLDER, "Package containing the consumer stubs for the " + service.getName() + " service.");
}
@Override
protected void createServiceProviderFolderComment(File structureFolder, AreaType area, ServiceType service) throws IOException {
createFolderComment(structureFolder, area, service, PROVIDER_FOLDER, "Package containing the provider skeletons for the " + service.getName() + " service.");
}
@Override
protected void createServiceMessageBodyFolderComment(String baseFolder, AreaType area, ServiceType service) throws IOException {
String basePackageName = getConfig().getAreaPackage(area.getName());
String packageName = basePackageName + "." + area.getName().toLowerCase();
if (null != service) {
packageName += "." + service.getName().toLowerCase();
}
ClassWriter file = createClassFile(baseFolder, (packageName + "." + getConfig().getBodyFolder() + "." + JAVA_PACKAGE_COMMENT_FILE_NAME).replace('.', '/'));
createFolderComment(file, area, service, getConfig().getBodyFolder(), "Package containing the types for holding compound messages.");
}
@Override
protected void createAreaStructureFolderComment(File structureFolder, AreaType area) throws IOException {
createFolderComment(structureFolder, area, null, getConfig().getStructureFolder(), "Package containing types defined in the " + area.getName() + " area.");
}
@Override
protected void createServiceStructureFolderComment(File structureFolder, AreaType area, ServiceType service) throws IOException {
createFolderComment(structureFolder, area, service, getConfig().getStructureFolder(), "Package containing types defined in the " + service.getName() + " service.");
}
@Override
protected void createStructureFactoryFolderComment(File structureFolder, AreaType area, ServiceType service) throws IOException {
createFolderComment(structureFolder, area, service, getConfig().getStructureFolder() + "." + getConfig().getFactoryFolder(), "Factory classes for the types defined in the "
+ ((null == service) ? (area.getName() + " area.") : (service.getName() + " service.")));
}
/**
* Creates a java package file.
*
* @param structureFolder The folder containing the generated code.
* @param area the area.
* @param service the server.
* @param extraPackage any extra package level.
* @param comment the comment.
* @throws IOException if there is a problem.
*/
protected void createFolderComment(File structureFolder, AreaType area, ServiceType service, String extraPackage, String comment) throws IOException {
ClassWriter file = createClassFile(structureFolder, JAVA_PACKAGE_COMMENT_FILE_NAME);
createFolderComment(file, area, service, extraPackage, comment);
}
/**
* Creates a java package file.
*
* @param file The folder containing the generated code.
* @param area the area.
* @param service the server.
* @param extraPackage any extra package level.
* @param comment the comment.
* @throws IOException if there is a problem.
*/
protected void createFolderComment(ClassWriter file, AreaType area, ServiceType service, String extraPackage, String comment) throws IOException {
file.addStatement("/**");
file.addStatement(comment);
file.addStatement("*/");
file.addPackageStatement(area, service, extraPackage);
file.flush();
}
@Override
protected CompositeField createCompositeElementsDetails(TargetWriter file, boolean checkType, String fieldName, TypeReference elementType, boolean isStructure, boolean canBeNull, String comment) {
CompositeField ele;
String typeName = elementType.getName();
if (checkType && !isKnownType(elementType)) {
getLog().warn("Unknown type (" + new TypeKey(elementType)
+ ") is being referenced as field (" + fieldName + ")");
}
if (elementType.isList()) {
// if (StdStrings.XML.equals(elementType.getArea()))
// {
// throw new IllegalArgumentException("XML type of (" + elementType.getService() + ":" + elementType.getName() + ") with maxOccurrs <> 1 is not permitted");
// }
// else
{
String fqTypeName;
if (isAttributeNativeType(elementType)) {
fqTypeName = createElementType((LanguageWriter) file, StdStrings.MAL, null, typeName + "List");
} else {
fqTypeName = createElementType((LanguageWriter) file, elementType, true) + "List";
}
String newCall = null;
String encCall = null;
if (!isAbstract(elementType) || isFullyPolymorphic()) {
newCall = "new " + fqTypeName + "()";
encCall = StdStrings.ELEMENT;
}
ele = new CompositeField(fqTypeName, elementType, fieldName, elementType.isList(), canBeNull, false, encCall, "(" + fqTypeName + ") ", StdStrings.ELEMENT, true, newCall, comment);
}
} else if (isAttributeType(elementType)) {
AttributeTypeDetails details = getAttributeDetails(elementType);
String fqTypeName = createElementType((LanguageWriter) file, elementType, isStructure);
ele = new CompositeField(details.getTargetType(), elementType, fieldName, elementType.isList(), canBeNull, false, typeName, "", typeName, false, "new " + fqTypeName + "()", comment);
} else {
TypeReference elementTypeIndir = elementType;
// have to work around the fact that JAXB does not replicate the XML type name into Java in all cases
if (StdStrings.XML.equalsIgnoreCase(elementType.getArea())) {
elementTypeIndir = TypeUtils.createTypeReference(elementType.getArea(), elementType.getService(), StubUtils.preCap(elementType.getName()), elementType.isList());
}
String fqTypeName = createElementType((LanguageWriter) file, elementTypeIndir, isStructure);
if (isEnum(elementType)) {
EnumerationType typ = getEnum(elementType);
String firstEle = fqTypeName + "." + typ.getItem().get(0).getValue();
ele = new CompositeField(fqTypeName, elementType, fieldName, elementType.isList(), canBeNull, false, StdStrings.ELEMENT, "(" + fqTypeName + ") ", StdStrings.ELEMENT, true, firstEle, comment);
} else if (StdStrings.ATTRIBUTE.equals(typeName)) {
ele = new CompositeField(fqTypeName, elementType, fieldName, elementType.isList(), canBeNull, false, StdStrings.ATTRIBUTE, "(" + fqTypeName + ") ", StdStrings.ATTRIBUTE, false, "", comment);
} else if (StdStrings.ELEMENT.equals(typeName)) {
ele = new CompositeField(fqTypeName, elementType, fieldName, elementType.isList(), canBeNull, false, StdStrings.ELEMENT, "(" + fqTypeName + ") ", StdStrings.ELEMENT, false, "", comment);
} else {
ele = new CompositeField(fqTypeName, elementType, fieldName, elementType.isList(), canBeNull, false, StdStrings.ELEMENT, "(" + fqTypeName + ") ", StdStrings.ELEMENT, true, "new " + fqTypeName + "()", comment);
}
}
return ele;
}
@Override
protected void addServiceConstructor(MethodWriter method, String serviceVar, String serviceVersion, ServiceSummary summary) throws IOException {
String opCall = serviceVar + "_SERVICE.addOperation(";
for (OperationSummary op : summary.getOperations()) {
method.addMethodStatement(opCall + op.getName().toUpperCase() + "_OP)");
}
}
@Override
protected String createAreaHelperClassInitialValue(String areaVar, short areaVersion) {
return "(" + areaVar + "_AREA_NUMBER, " + areaVar + "_AREA_NAME, new org.ccsds.moims.mo.mal.structures.UOctet((short) " + areaVersion + "))";
}
@Override
protected String createServiceHelperClassInitialValue(String serviceVar) {
return "(" + serviceVar + "_SERVICE_NUMBER, " + serviceVar + "_SERVICE_NAME)";
}
@Override
protected String getIntCallMethod() {
return "intValue";
}
@Override
protected String getOctetCallMethod() {
return "byteValue";
}
@Override
protected String getRegisterMethodName() {
return "register";
}
@Override
protected String getDeregisterMethodName() {
return "deregister";
}
@Override
protected String getEnumValueCompare(String lhs, String rhs) {
return lhs + ".equals(" + rhs + ")";
}
@Override
protected String getEnumEncoderValue(long maxValue) {
String enumEncoderValue = "new org.ccsds.moims.mo.mal.structures.UInteger(ordinal.longValue())";
if (maxValue < 256) {
enumEncoderValue = "new org.ccsds.moims.mo.mal.structures.UOctet(ordinal.shortValue())";
} else if (maxValue < 65536) {
enumEncoderValue = "new org.ccsds.moims.mo.mal.structures.UShort(ordinal.intValue())";
}
return enumEncoderValue;
}
@Override
protected String getEnumDecoderValue(long maxValue) {
return ".getValue()";
}
@Override
protected String getNullValue() {
return "null";
}
@Override
protected void addVectorAddStatement(LanguageWriter file, MethodWriter method, String variable, String parameter) throws IOException {
method.addMethodStatement(variable + ".addElement(" + parameter + ")");
}
@Override
protected void addVectorRemoveStatement(LanguageWriter file, MethodWriter method, String variable, String parameter) throws IOException {
method.addMethodStatement(variable + ".removeElement(" + parameter + ")");
}
@Override
protected String createStaticClassReference(String type) {
return type + ".class";
}
@Override
protected String addressOf(String type) {
return type;
}
@Override
protected String createArraySize(boolean isActual, String type, String variable) {
return variable + ".length";
}
@Override
protected String malStringAsElement(LanguageWriter file) {
return createElementType(file, StdStrings.MAL, null, StdStrings.UNION);
}
@Override
protected String errorCodeAsReference(LanguageWriter file, String ref) {
return ref;
}
@Override
protected ClassWriterProposed createClassFile(File folder, String className) throws IOException {
return new JavaClassWriter(folder, className);
}
@Override
protected ClassWriter createClassFile(String destinationFolderName, String className) throws IOException {
return new JavaClassWriter(destinationFolderName, className);
}
@Override
protected InterfaceWriter createInterfaceFile(File folder, String className) throws IOException {
return new JavaClassWriter(folder, className);
}
@Override
protected InterfaceWriter createInterfaceFile(String destinationFolderName, String className) throws IOException {
return new JavaClassWriter(destinationFolderName, className);
}
private class JavaClassWriter extends AbstractLanguageWriter implements ClassWriterProposed, InterfaceWriter, MethodWriter {
private final Writer file;
/**
* Constructor.
*
* @param folder The folder to create the file in.
* @param className The class name.
* @throws IOException If any problems creating the file.
*/
public JavaClassWriter(File folder, String className) throws IOException {
file = StubUtils.createLowLevelWriter(folder, className, JAVA_FILE_EXT);
}
/**
* Constructor.
*
* @param destinationFolderName Folder to create the file in.
* @param className The file name.
* @throws IOException If any problems creating the file.
*/
public JavaClassWriter(String destinationFolderName, String className) throws IOException {
file = StubUtils.createLowLevelWriter(destinationFolderName, className, JAVA_FILE_EXT);
}
@Override
public void addStatement(String string) throws IOException {
file.append(addFileStatement(0, string, false));
}
@Override
public void addClassCloseStatement() throws IOException {
file.append(addFileStatement(0, "}", false));
}
@Override
public void addClassOpenStatement(String className, boolean finalClass, boolean abstractClass, String extendsClass, String implementsInterface, String comment) throws IOException {
addMultilineComment(0, true, comment, false);
file.append("public ");
if (finalClass) {
file.append("final ");
}
if (abstractClass) {
file.append("abstract ");
}
file.append("class " + className);
if (null != extendsClass) {
file.append(" extends " + extendsClass);
}
if (null != implementsInterface) {
file.append(" implements " + implementsInterface);
}
file.append(getLineSeparator());
file.append(addFileStatement(0, "{", false));
}
@Override
public void addClassVariableProposed(boolean isStatic, boolean isFinal, String scope, CompositeField arg, boolean isObject, String initialValue) throws IOException {
addClassVariable(true, isStatic, isFinal, scope, arg, isObject, false, initialValue);
}
@Override
public void addClassVariable(boolean isStatic, boolean isFinal, String scope, CompositeField arg, boolean isObject, String initialValue) throws IOException {
addClassVariable(false, isStatic, isFinal, scope, arg, isObject, false, initialValue);
}
@Override
public void addClassVariable(boolean isStatic, boolean isFinal, String scope, CompositeField arg, boolean isObject, boolean isArray, List initialValue) throws IOException {
StringBuilder iniVal = new StringBuilder();
for (int i = 0; i < initialValue.size(); i++) {
if (0 < i) {
iniVal.append(", ");
}
iniVal.append(initialValue.get(i));
}
String val;
if (isArray) {
val = iniVal.toString();
} else {
val = "(" + iniVal.toString() + ")";
}
addClassVariable(false, isStatic, isFinal, scope, arg, isObject, isArray, val);
}
protected void addClassVariable(boolean isProposed, boolean isStatic, boolean isFinal, String scope, CompositeField arg, boolean isObject, boolean isArray, String initialValue) throws IOException {
addMultilineComment(1, false, arg.getComment(), false);
StringBuilder buf = new StringBuilder(scope);
buf.append(" ");
if (isStatic) {
buf.append("static ");
}
if (isFinal) {
buf.append("final ");
}
String ltype = createLocalType(arg);
buf.append(ltype);
if (isArray) {
buf.append("[]");
}
buf.append(" ");
buf.append(arg.getFieldName());
if (null != initialValue) {
if (isArray) {
buf.append(" = {").append(initialValue).append("}");
} else if (isNativeType(arg.getTypeName())) {
NativeTypeDetails dets = getNativeType(arg.getTypeName());
if (dets.isObject()) {
buf.append(" = new ").append(ltype).append(initialValue);
} else {
buf.append(" = ").append(initialValue);
}
} else {
buf.append(" = new ").append(ltype).append(initialValue);
}
}
if (isProposed) {
file.append(addFileStatement(1, "@org.ccsds.moims.mo.com.Proposed", false));
}
file.append(addFileStatement(1, buf.toString(), true));
}
@Override
public void addStaticConstructor(String returnType, String methodName, String args, String constructorCall) throws IOException {
}
@Override
public void addConstructorDefault(String className) throws IOException {
addMultilineComment(1, false, "Default constructor for " + className, false);
addConstructor(StdStrings.PUBLIC, className, null, null, null, null, null).addMethodCloseStatement();
}
@Override
public void addConstructorCopy(String className, List compElements) throws IOException {
}
@Override
public MethodWriter addConstructor(String scope, String className, CompositeField arg, boolean isArgForSuper, String throwsSpec, String comment, String throwsComment) throws IOException {
return addConstructor(scope, className, Arrays.asList(arg), (isArgForSuper ? Arrays.asList(arg) : ((List) null)), throwsSpec, comment, throwsComment);
}
@Override
public MethodWriter addConstructor(String scope, String className, List args, List superArgs, String throwsSpec, String comment, String throwsComment) throws IOException {
addMultilineComment(1, false, normaliseArgComments(comment, null, args, Arrays.asList(throwsComment)), false);
StringBuilder buf = new StringBuilder(scope + " " + className + "(" + processArgs(args, true) + ")");
if (null != throwsSpec) {
buf.append(" throws ");
buf.append(throwsSpec);
}
file.append(addFileStatement(1, buf.toString(), false));
file.append(addFileStatement(1, "{", false));
if ((null != superArgs) && (0 < superArgs.size())) {
file.append(addFileStatement(2, "super(" + processArgs(superArgs, false) + ")", true));
}
return this;
}
@Override
public MethodWriter addMethodOpenStatement(boolean isConst, boolean isStatic, String scope, boolean isReturnConst, boolean isReturnActual, CompositeField rtype, String methodName, List args, String throwsSpec) throws IOException {
return addMethodOpenStatement(isConst, isStatic, scope, isReturnConst, isReturnActual, rtype, methodName, args, throwsSpec, null, null, null);
}
@Override
public MethodWriter addMethodOpenStatement(boolean isConst, boolean isStatic, String scope, boolean isReturnConst, boolean isReturnActual, CompositeField rtype, String methodName, List args, String throwsSpec, String comment, String returnComment, List throwsComment) throws IOException {
return addMethodOpenStatement(false, isConst, isStatic, scope, isReturnConst, isReturnActual, rtype, methodName, args, throwsSpec, comment, returnComment, throwsComment);
}
@Override
public MethodWriter addMethodOpenStatement(boolean isVirtual, boolean isConst, boolean isStatic, String scope, boolean isReturnConst, boolean isReturnActual, CompositeField rtype, String methodName, List args, String throwsSpec) throws IOException {
return addMethodOpenStatement(isVirtual, isConst, isStatic, scope, isReturnConst, isReturnActual, rtype, methodName, args, throwsSpec, null, null, null);
}
@Override
public MethodWriter addMethodOpenStatement(boolean isVirtual, boolean isConst, boolean isStatic, String scope, boolean isReturnConst, boolean isReturnActual, CompositeField rtype, String methodName, List args, String throwsSpec, String comment, String returnComment, List throwsComment) throws IOException {
return addMethodOpenStatement(false, isVirtual, isConst, isStatic, scope, isReturnConst, isReturnActual, rtype, methodName, args, throwsSpec, comment, returnComment, throwsComment);
}
@Override
public MethodWriter addMethodOpenStatement(boolean isFinal, boolean isVirtual, boolean isConst, boolean isStatic, String scope, boolean isReturnConst, boolean isReturnActual, CompositeField rtype, String methodName, List args, String throwsSpec, String comment, String returnComment, List throwsComment) throws IOException {
addMultilineComment(1, false, normaliseArgComments(comment, returnComment, args, throwsComment), false);
String nStatic = "";
if (isStatic) {
nStatic = "static ";
}
String nFinal = "";
if (isFinal) {
nFinal = "final ";
}
String srtype = createLocalType(rtype);
String argString = processArgs(args, true);
StringBuilder buf = new StringBuilder(scope + " " + nStatic + nFinal + srtype + " " + methodName + "(" + argString + ")");
if (null != throwsSpec) {
buf.append(" throws ");
buf.append(throwsSpec);
}
file.append(addFileStatement(1, buf.toString(), false));
file.append(addFileStatement(1, "{", false));
return this;
}
@Override
public void addPackageStatement(AreaType area, ServiceType service, String extraPackage) throws IOException {
String packageName = "";
if (null == area) {
packageName = getConfig().getAreaPackage("");
} else {
packageName += getConfig().getAreaPackage(area.getName()) + area.getName().toLowerCase();
if (null != service) {
packageName += "." + service.getName().toLowerCase();
}
}
if (null != extraPackage) {
if (0 < packageName.length()) {
packageName += ".";
}
packageName += extraPackage;
}
file.append(addFileStatement(0, "package " + packageName, true));
}
@Override
public void flush() throws IOException {
file.flush();
}
@Override
public void addInterfaceCloseStatement() throws IOException {
file.append(addFileStatement(0, "}", false));
}
@Override
public void addInterfaceMethodDeclaration(String scope, CompositeField rtype, String methodName, List args, String throwsSpec, String comment, String returnComment, List throwsComment) throws IOException {
String srtype = createLocalType(rtype);
String argString = processArgs(args, true);
addMultilineComment(1, false, normaliseArgComments(comment, null == rtype ? null : returnComment, args, throwsComment), false);
StringBuilder buf = new StringBuilder(srtype + " " + methodName + "(" + argString + ")");
if (null != throwsSpec) {
buf.append(" throws ");
buf.append(throwsSpec);
}
file.append(addFileStatement(1, buf.toString(), true));
}
@Override
public void addInterfaceOpenStatement(String interfaceName, String extendsInterface, String comment) throws IOException {
addMultilineComment(0, true, comment, false);
file.append("public interface ");
file.append(interfaceName);
if (null != extendsInterface) {
file.append(" extends " + extendsInterface);
}
file.append(getLineSeparator());
file.append(addFileStatement(0, "{", false));
}
@Override
public void addArrayMethodStatement(String arrayVariable, String indexVariable, String arrayMaxSize) throws IOException {
addMethodStatement("return " + arrayVariable + "[" + indexVariable + "]", true);
}
@Override
public void addSuperMethodStatement(String method, String args) throws IOException {
addMethodStatement("super." + method + "(" + args + ")", true);
}
@Override
public void addMethodStatement(String statement) throws IOException {
addMethodStatement(statement, true);
}
@Override
public void addMethodWithDependencyStatement(String statement, String dependency, boolean addSemi) throws IOException {
addMethodStatement(statement, addSemi);
}
@Override
public void addMethodStatement(String statement, boolean addSemi) throws IOException {
if (0 < statement.trim().length()) {
file.append(addFileStatement(2, statement, addSemi));
}
}
@Override
public void addMethodCloseStatement() throws IOException {
file.append(addFileStatement(1, "}", false));
file.append(getLineSeparator());
}
@Override
public void addMultilineComment(int tabCount, boolean preBlankLine, List comments, boolean postBlankLine) throws IOException {
if (0 < comments.size()) {
if (preBlankLine) {
file.append(getLineSeparator());
}
file.append(addFileStatement(tabCount, "/**", false));
for (String comment : comments) {
file.append(addFileStatement(tabCount, " * " + comment, false));
}
file.append(addFileStatement(tabCount, " */", false));
if (postBlankLine) {
file.append(getLineSeparator());
}
}
}
private List normaliseArgComments(String comment, String returnComment, List argsComments, List throwsComment) {
List rv = new LinkedList();
if (null != argsComments) {
for (CompositeField arg : argsComments) {
rv.add(arg.getFieldName() + " " + arg.getComment());
}
}
return normaliseComments(comment, returnComment, rv, throwsComment);
}
private List normaliseComments(String comment, String returnComment, List argsComments, List throwsComment) {
List rv = new LinkedList();
normaliseComment(rv, comment);
normaliseComments(rv, StubUtils.conditionalAdd("@param ", argsComments));
normaliseComment(rv, StubUtils.conditionalAdd("@return ", returnComment));
normaliseComments(rv, StubUtils.conditionalAdd("@throws ", throwsComment));
return rv;
}
private String processArgs(List args, boolean includeType) {
StringBuilder buf = new StringBuilder();
if (null != args && (0 < args.size())) {
boolean firstTime = true;
for (CompositeField arg : args) {
if (firstTime) {
firstTime = false;
} else {
buf.append(", ");
}
if (includeType) {
buf.append(createLocalType(arg)).append(" ");
}
String name = checkForReservedWords(arg.getFieldName());
buf.append(name);
}
}
return buf.toString();
}
private String createLocalType(CompositeField type) {
if (null != type) {
if (isNativeType(type.getTypeName())) {
NativeTypeDetails dets = getNativeType(type.getTypeName());
return dets.getLanguageTypeName();
} else if (!type.isList() && isAttributeType(type.getTypeReference())) {
AttributeTypeDetails dets = getAttributeDetails(type.getTypeReference());
if (null != dets) {
return dets.getTargetType();
}
}
return type.getTypeName();
}
return StdStrings.VOID;
}
// private String createLocalType(String type)
// {
// if (null != type)
// {
// String head = "";
// String tail = "";
//
// if (type.startsWith("new "))
// {
// head = "new ";
// int tindex = type.indexOf('(');
//
// if (tindex == -1)
// {
// tindex = type.indexOf('[');
// }
//
// tail = type.substring(tindex);
// type = type.substring(4, type.length() - tail.length());
// }
//
// if (isNativeType(type))
// {
// NativeTypeDetails dets = getNativeType(type);
//
// type = dets.getLanguageTypeName();
// }
// else
// {
// AttributeTypeDetails dets = getAttributeDetails(type);
// if (null != dets)
// {
// type = dets.getTargetType();
// }
// }
//
// return head + type + tail;
// }
//
// return type;
// }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy