/**
* Copyright (C) 2015 Orange
* Licensed 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 com.francetelecom.clara.cloud.logicalmodel;
import com.francetelecom.clara.cloud.commons.GuiMapping;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.*;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* This abstract class factors out the generic behaviors common to all of the persistence model classes.
*
* TODO Factorisation :
* - du champ version pour le verouillage optimiste
* - du champ nom
* - de la methode toString() pour l'affichage du contenu d'un objet persistant
*
* @author Clara
*/
@XmlAccessorType(XmlAccessType.FIELD)
@MappedSuperclass
public abstract class LogicalEntity implements Serializable {
@XmlTransient
@Transient
@GuiMapping(status = GuiMapping.StatusType.NA)
private SimpleDateFormat sdf;
/**
* version for optimistic lock Be careful : no setter/getter on version,
* only jpa is able to set/get versions
*/
@XmlAttribute
@Version
@GuiMapping(status = GuiMapping.StatusType.NA)
protected int version;
/**
* Human readeable name of a logical entity.
*
* Should be unique within the logical deployment scope.
* Note: Watch subclasses for javadoc comments about subclasses that require different {@link GuiMapping} for this field such as {@link LogicalDeployment}
*
* This maps to bug #80111, mingle #1344
*/
@XmlID
@XmlAttribute
@Column(unique = true, length = 150)
@NotNull
@GuiMapping(status = GuiMapping.StatusType.SKIPPED)
protected String name;
protected static final String[] EXCLUDED_EQUALS_FIELDS = new String[] {"name", "sdf", "version"};
@Override
public boolean equals(Object obj) {
//See http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/builder/EqualsBuilder.html
return EqualsBuilder.reflectionEquals(this, obj, EXCLUDED_EQUALS_FIELDS);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, EXCLUDED_EQUALS_FIELDS);
}
public String toString() {
return (new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) {
protected boolean accept(Field f) {
return super.accept(f) && ! isFieldExcludedFromToString(f.getName());
}
protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException {
//Try to sort all of our collections so that toString() comparison is easier
Class<?> type = field.getType();
if (List.class.isAssignableFrom(type)) {
List list = (List) field.get(this.getObject());
List sortedList = new ArrayList(list);
Collections.sort(sortedList);
return sortedList;
}
return field.get(this.getObject());
}
}).toString();
}
/**
* Override this method in subclasses to specify the list of excluded to not display fields
* (usually the same list as equals)
*/
protected boolean isFieldExcludedFromToString(String fieldName) {
return isFieldExcludedFromToString(fieldName, LogicalEntity.EXCLUDED_EQUALS_FIELDS);
}
/**
* Utility method to define fields which should be ommited from {@link #toString}. This is called
* by subclasses.
*/
protected boolean isFieldExcludedFromToString(String fieldName, String[] excludedEqualsFields) {
for (String excludedEqualsField : excludedEqualsFields) {
if (excludedEqualsField.equals(fieldName)) {
return true;
}
}
return false;
}
/**
*
* @return
*/
public String getName() {
return name;
}
/**
* only used by LogicalDeployment
* @param name
*/
// protected final void setName(String name) {
// // TODO : once test will be OK uncomment this line and modify method visibility to protected
// if (this.name != null) throw new IllegalArgumentException("name is supposed to be immutable (current is "+this.name+")");
// this.name = name;
// }
}