blob: e3ed68ccf1a6bcb0ae5ed827d87c1db4c764dd3a [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.ecview.dsl.extensions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.eclipse.osbp.runtime.common.annotations.AsGrid;
import org.eclipse.osbp.runtime.common.annotations.AsTable;
import org.eclipse.osbp.runtime.common.annotations.BeanOnTab;
import org.eclipse.osbp.runtime.common.annotations.CreateAt;
import org.eclipse.osbp.runtime.common.annotations.CreateBy;
import org.eclipse.osbp.runtime.common.annotations.Dirty;
import org.eclipse.osbp.runtime.common.annotations.Hidden;
import org.eclipse.osbp.runtime.common.annotations.Id;
import org.eclipse.osbp.runtime.common.annotations.ReadOnly;
import org.eclipse.osbp.runtime.common.annotations.SideKick;
import org.eclipse.osbp.runtime.common.annotations.UIGroup;
import org.eclipse.osbp.runtime.common.annotations.UpdateAt;
import org.eclipse.osbp.runtime.common.annotations.UpdateBy;
import org.eclipse.osbp.runtime.common.annotations.Version;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmAnnotationValue;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmFeature;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmStringAnnotationValue;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmVisibility;
import org.eclipse.xtext.xbase.lib.StringExtensions;
/**
* The Class OperationExtensions.
*/
public class OperationExtensions {
/**
* Normalizes the method name.
*
* @param simpleName
* the simple name
* @return the string
*/
public static String toPropertyName(String simpleName) {
if (simpleName == null) {
return null;
}
String tempName = null;
if (isSetter(simpleName)) {
tempName = StringExtensions.toFirstLower(simpleName.replaceFirst("set", ""));
} else if (isGetter(simpleName)) {
if (simpleName.startsWith("get")) {
tempName = StringExtensions.toFirstLower(simpleName.replaceFirst("get", ""));
} else {
tempName = StringExtensions.toFirstLower(simpleName.replaceFirst("is", ""));
}
}
return tempName;
}
/**
* Checks if is getter.
*
* @param simpleName
* the simple name
* @return true, if is getter
*/
public static boolean isGetter(String simpleName) {
if (simpleName == null) {
return false;
}
return simpleName.startsWith("get") || simpleName.startsWith("is");
}
/**
* Checks if is setter.
*
* @param simpleName
* the simple name
* @return true, if is setter
*/
public static boolean isSetter(String simpleName) {
return simpleName != null && simpleName.startsWith("set");
}
/**
* Calculates the operation infos for the given type.
*
* @param type
* the type
* @return the operation infos
*/
public static Map<String, OperationInfo> getOperationInfos(JvmDeclaredType type) {
return getOperationInfos(type, true);
}
/**
* Calculates the operation infos for the given type.
*
* @param type
* @return
*/
public static Map<String, OperationInfo> getOperationInfos(JvmDeclaredType type, boolean includeSuperType) {
// Changed from HashMap to LinkedHashMap due to #203.
Map<String, OperationInfo> infos = new LinkedHashMap<String, OperationInfo>();
List<JvmFeature> fields = StreamSupport.stream(type.getAllFeatures().spliterator(), false).filter(f->type == f.eContainer()).collect(Collectors.toList());
List<JvmFeature> allFields = StreamSupport.stream(type.getAllFeatures().spliterator(), false).collect(Collectors.toList());
allFields.removeAll(fields);
allFields.addAll(fields);
extractFields(type, includeSuperType, infos, allFields);
// apply readonly and create descriptions
for (OperationInfo info : infos.values()) {
if (info.getter == null) {
continue;
}
if (info.setter == null) {
info.readonly = true;
}
}
for (JvmFeature feature : type.getAllFeatures()) {
if (feature instanceof JvmField) {
JvmField field = (JvmField) feature;
String id = calcFieldId(field.getDeclaringType(), field.getSimpleName());
if (infos.containsKey(id)) {
OperationInfo info = infos.get(id);
info.setField(field);
}
}
}
return infos;
}
private static void extractFields(JvmDeclaredType type, boolean includeSuperType, Map<String, OperationInfo> infos,
List<JvmFeature> allFields) {
for (JvmFeature feature : allFields) {
if (!includeSuperType) {
if (type != feature.eContainer()) {
continue;
}
}
if (!(feature instanceof JvmOperation)) {
continue;
}
JvmOperation operation = (JvmOperation) feature;
if (operation.getVisibility() != JvmVisibility.PUBLIC) {
continue;
}
if (!isSetter(operation.getSimpleName()) && operation.getParameters().size() > 1) {
continue;
}
String propertyName = toPropertyName(operation.getSimpleName());
if (propertyName == null) {
continue;
}
// TODO Pirchner - Find a solution for it -> Check by added
// annotations for @Dispose, @Dirty,...
// if (propertyName.equals("disposed") || propertyName.equals("id")
// || propertyName.equals("uuid")) {
if (propertyName.equals("disposed")) {
continue;
}
if (!isGetter(operation.getSimpleName()) && !isSetter(operation.getSimpleName())) {
continue;
}
String id = calcId(operation.getDeclaringType(), operation.getSimpleName());
if (!infos.containsKey(id)) {
OperationInfo info = new OperationInfo();
info.id = id;
info.name = propertyName;
infos.put(id, info);
}
OperationInfo info = infos.get(id);
if (isGetter(operation.getSimpleName())) {
info.getter = operation;
} else {
// TODO fix this hack
if (!propertyName.equals("dirty")) {
info.setter = operation;
}
}
}
}
/**
* Normalizes the name.
*
* @param declaringType
* the declaring type
* @param simpleName
* the simple name
* @return the string
*/
public static String calcId(JvmDeclaredType declaringType, String simpleName) {
String tempName = toPropertyName(simpleName);
if (tempName == null) {
return null;
}
return declaringType.getQualifiedName() + ":" + tempName;
}
/**
* Normalizes the name.
*
* @param declaringType
* the declaring type
* @param simpleName
* the simple name
* @return the string
*/
public static String calcFieldId(JvmDeclaredType declaringType, String simpleName) {
return declaringType.getQualifiedName() + ":" + simpleName;
}
/**
* The Class OperationInfo.
*/
public static class OperationInfo {
/** The id. */
private String id;
/** The name. */
private String name;
/** The readonly. */
private boolean readonly;
/** The getter. */
private JvmOperation getter;
/** The setter. */
private JvmOperation setter;
/** The field. */
private JvmField field;
/**
* Gets the id.
*
* @return the id
*/
public String getId() {
return id;
}
/**
* Sets the id.
*
* @param id
* the new id
*/
public void setId(String id) {
this.id = id;
}
/**
* Gets the name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Sets the name.
*
* @param name
* the new name
*/
public void setName(String name) {
this.name = name;
}
/**
* Checks if is readonly.
*
* @return true, if is readonly
*/
public boolean isReadonly() {
if(isAnnotatedReadOnly()) {
return true;
}
return readonly;
}
/**
* Sets the readonly.
*
* @param readonly
* the new readonly
*/
public void setReadonly(boolean readonly) {
this.readonly = readonly;
}
/**
* Returns true, if the info has an annotation matching the given
* annotationType.
*
* @param annotationType
* @return
*/
public boolean hasAnnotation(Class<?> annotationType) {
if (field == null) {
return false;
}
for (JvmAnnotationReference annotation : field.getAnnotations()) {
if (annotation.getAnnotation().getQualifiedName().equals(annotationType.getName())) {
return true;
}
}
return false;
}
/**
* Returns true, if the field is and id or uuid.
*
* @return
*/
public boolean isIdOrUUID() {
return hasAnnotation(Id.class);
}
/**
* Returns true, if the field is a version field.
*
* @return
*/
public boolean isVersion() {
return hasAnnotation(Version.class);
}
/**
* Returns true, if the field is a dirty field.
*
* @return
*/
public boolean isDirtyMark() {
return hasAnnotation(Dirty.class);
}
public boolean isHidden() {
return hasAnnotation(Hidden.class);
}
public boolean isAnnotatedReadOnly() {
return hasAnnotation(ReadOnly.class);
}
public boolean isDatabaseInfo() {
if(hasAnnotation(UpdateAt.class) || hasAnnotation(UpdateBy.class) || hasAnnotation(CreateAt.class) || hasAnnotation(CreateBy.class)) {
return true;
}
return false;
}
public boolean isGroupMember() {
return hasAnnotation(UIGroup.class);
}
public String getGroupMemberName() {
if (field == null) {
return null;
}
for (JvmAnnotationReference annotation : field.getAnnotations()) {
if (annotation.getAnnotation().getQualifiedName().equals(UIGroup.class.getName())) {
for(JvmAnnotationValue value : annotation.getValues()) {
if(value instanceof JvmStringAnnotationValue) {
return ((JvmStringAnnotationValue)value).getValues().get(0);
}
}
}
}
return null;
}
public boolean asGrid() {
return hasAnnotation(AsGrid.class);
}
public boolean asTable() {
return hasAnnotation(AsTable.class);
}
public boolean beanOnTab() {
return hasAnnotation(BeanOnTab.class);
}
public boolean sideKick() {
return hasAnnotation(SideKick.class);
}
/**
* Gets the getter.
*
* @return the getter
*/
public JvmOperation getGetter() {
return getter;
}
/**
* Sets the getter.
*
* @param getter
* the new getter
*/
public void setGetter(JvmOperation getter) {
this.getter = getter;
}
/**
* Gets the setter.
*
* @return the setter
*/
public JvmOperation getSetter() {
return setter;
}
/**
* Sets the setter.
*
* @param setter
* the new setter
*/
public void setSetter(JvmOperation setter) {
this.setter = setter;
}
/**
* Gets the field.
*
* @return the field
*/
public JvmField getField() {
return field;
}
/**
* Sets the field.
*
* @param field
* the new field
*/
public void setField(JvmField field) {
this.field = field;
}
}
}