/** * <copyright> * * Copyright (c) 2009, 2010 Springsite BV (The Netherlands), IBM Corporation and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Martin Taal - Initial API and implementation * IBM - default value handling * * </copyright> * * $Id: ModelEDataTypeAnnotator.java,v 1.19 2011/08/25 12:35:07 mtaal Exp $ */ package org.eclipse.emf.texo.modelgenerator.annotator; import java.util.Locale; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.ecore.util.ExtendedMetaData; import org.eclipse.emf.texo.generator.Annotator; import org.eclipse.emf.texo.generator.GeneratorUtils; import org.eclipse.emf.texo.modelgenerator.modelannotations.EDataTypeModelGenAnnotation; import org.eclipse.emf.texo.modelgenerator.modelannotations.EDataTypeModelGenAnnotationDefinition; import org.eclipse.emf.texo.modelgenerator.modelannotations.EPackageModelGenAnnotation; import org.eclipse.emf.texo.modelgenerator.modelannotations.ModelcodegeneratorPackage; import org.eclipse.emf.texo.utils.Check; import org.eclipse.emf.texo.utils.ModelUtils; /** * Responsible for setting the values in a {@link EDataTypeModelGenAnnotation}. * * Note: the code related to default value handling originates to a large extent from the GenDataTypeImpl class which is * part of EMF core. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> * @version $Revision: 1.19 $ */ public class ModelEDataTypeAnnotator extends ModelEClassifierAnnotator implements Annotator<EDataTypeModelGenAnnotation> { /* * (non-Javadoc) * * @see org.eclipse.emf.texo.generator.Annotator#getAnnotationEClass() */ @Override public EClass getAnnotationEClass() { return ModelcodegeneratorPackage.eINSTANCE.getEDataTypeModelGenAnnotation(); } /* * (non-Javadoc) * * @see org.eclipse.emf.texo.generator.Annotator#annotate(org.eclipse.emf.texo.annotations.annotationsmodel * .ENamedElementAnnotation) */ public void setAnnotationFeatures(EDataTypeModelGenAnnotation annotation) { super.annotate(annotation); Check.isNotNull(annotation.getEDataType(), "eDataType must be set");//$NON-NLS-1$ final EDataType eDataType = annotation.getEDataType(); if (!annotation.isSetEnum()) { annotation.setEnum(eDataType instanceof EEnum); } final EEnum eEnumBaseType = ModelUtils.getEnumBaseDataTypeIfObject(eDataType); final boolean isTypeWithEnumBaseType = eEnumBaseType != null; final String instanceClassName; if (!GeneratorUtils.isEmptyOrNull(annotation.getInstanceClassName())) { instanceClassName = annotation.getInstanceClassName(); } else if (isTypeWithEnumBaseType) { instanceClassName = getInstanceClassNameForEnum(eEnumBaseType); } else { instanceClassName = getInstanceClassName(eDataType); } final Class<?> instanceClass = getInstanceClass(eDataType, instanceClassName); if (!annotation.isSetDateType()) { if (isTypeWithEnumBaseType) { annotation.setDateType(false); } else if (GenUtils.isDateOrDateTime(eDataType)) { annotation.setDateType(true); } else { annotation.setDateType(false); } } // find the item type, if not found directly try to find it in the basetype EDataType itemDataType = ExtendedMetaData.INSTANCE.getItemType(annotation.getEDataType()); EDataType baseType = annotation.getEDataType(); while (itemDataType == null && (baseType = ExtendedMetaData.INSTANCE.getBaseType(baseType)) != null) { itemDataType = ExtendedMetaData.INSTANCE.getItemType(baseType); } if (itemDataType != null) { final EDataTypeModelGenAnnotationDefinition itemDataTypeAnnotation = getEDataTypeModelGenAnnotation(itemDataType); annotation.setItemType(itemDataTypeAnnotation.getInstanceClassName()); } if (GeneratorUtils.isEmptyOrNull(annotation.getObjectClassName())) { if (isTypeWithEnumBaseType) { annotation.setObjectClassName(instanceClassName); } else if (instanceClass != null && instanceClass.isArray()) { annotation.setObjectClassName(instanceClass.getComponentType() + "[]"); //$NON-NLS-1$ } else if (instanceClass != null && instanceClass.getTypeParameters().length > 0 && annotation.getItemType() != null) { // currently only one type parameter is supported annotation.setObjectClassName(instanceClass.getName() + "<" + annotation.getItemType() //$NON-NLS-1$ + ">"); //$NON-NLS-1$ } else { annotation.setObjectClassName(GenUtils.getObjectClassName(eDataType, instanceClassName)); } } // set the item type equal to the object classname for safety reason if (GeneratorUtils.isEmptyOrNull(annotation.getItemType())) { annotation.setItemType(annotation.getObjectClassName()); } if (GeneratorUtils.isEmptyOrNull(annotation.getQualifiedClassName())) { annotation.setQualifiedClassName(instanceClassName); } if (GeneratorUtils.isEmptyOrNull(annotation.getInstanceClassName())) { annotation.setInstanceClassName(instanceClassName); } if (GeneratorUtils.isEmptyOrNull(annotation.getSimpleClassName())) { annotation.setSimpleClassName(getSimpleClassName(eDataType)); } if (!annotation.isSetGenerateCode()) { annotation.setGenerateCode(true); } if (!annotation.isSetAutomaticStringConversion()) { if (isTypeWithEnumBaseType) { annotation.setAutomaticStringConversion(false); } else { annotation.setAutomaticStringConversion(hasInstanceClassStringConstructor(instanceClass)); } } final EPackageModelGenAnnotation ePackageAnnotation = getEPackageModelGenAnnotation(eDataType.getEPackage()); annotation.setOwnerEPackageAnnotation(ePackageAnnotation); if (isTypeWithEnumBaseType) { final EDataTypeModelGenAnnotationDefinition baseTypeAnnotation = getEDataTypeModelGenAnnotation(eEnumBaseType); annotation.setBaseTypeAnnotation(baseTypeAnnotation); } } /* * (non-Javadoc) * * @seeorg.eclipse.emf.texo.generator.Annotator#postAnnotating(org.eclipse.emf.texo.annotations. * annotationsmodel.ENamedElementAnnotation) */ public void postAnnotating(EDataTypeModelGenAnnotation annotation) { } private Class<?> getInstanceClass(EDataType eDataType, String instanceClassName) { return getClassForName(eDataType, instanceClassName); } private String getInstanceClassName(EDataType eDataType) { return GenUtils.getInstanceClassName(eDataType); } /** * @return true if the instance class is not null (see {@link #getInstanceClass()} and it has a constructor with a * single String constructor. */ private boolean hasInstanceClassStringConstructor(Class<?> instanceClass) { if (instanceClass == null) { return false; } try { Class<?> useClass = instanceClass; if (!useClass.getName().contains(".")) { //$NON-NLS-1$ useClass = GenUtils.getObjectClass(instanceClass); if (useClass == null) { return false; } } useClass.getConstructor(String.class); return true; } catch (final NoSuchMethodException e) { return false; } } protected String getInstanceClassNameForEnum(EEnum eEnum) { final EPackageModelGenAnnotation annotation = getEPackageModelGenAnnotation(eEnum.getEPackage()); final String qualifiedClassName = annotation.getPackagePath().toLowerCase(Locale.ENGLISH) + GenConstants.DOT + getSimpleClassName(eEnum); return qualifiedClassName; } }