/*
* ====================================================================
*
* The ObjectStyle Group Software License, Version 1.0
*
* Copyright (c) 2006 The ObjectStyle Group and individual authors of the
* software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowlegement: "This product includes software
* developed by the ObjectStyle Group (http://objectstyle.org/)." Alternately,
* this acknowlegement may appear in the software itself, if and wherever such
* third-party acknowlegements normally appear.
*
* 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse or
* promote products derived from this software without prior written permission.
* For written permission, please contact andrus@objectstyle.org.
*
* 5. Products derived from this software may not be called "ObjectStyle" nor
* may "ObjectStyle" appear in their names without prior written permission of
* the ObjectStyle Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* OBJECTSTYLE GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many individuals on
* behalf of the ObjectStyle Group. For more information on the ObjectStyle
* Group, please see <http://objectstyle.org/>.
*
*/
package org.objectstyle.wolips.eomodeler.core.model;
import java.util.Set;
import org.objectstyle.wolips.baseforplugins.util.ComparisonUtils;
import org.objectstyle.wolips.baseforplugins.util.StringUtils;
public abstract class AbstractEOArgument<T extends EOModelObject> extends UserInfoableEOModelObject<T> implements ISortableEOModelObject {
public static final String ALLOWS_NULL = "allowsNull";
public static final String NAME = "name";
public static final String COLUMN_NAME = "columnName";
public static final String ADAPTOR_VALUE_CONVERSION_CLASS_NAME = "adaptorValueConversionClassName";
public static final String ADAPTOR_VALUE_CONVERSION_METHOD_NAME = "adaptorValueConversionMethodName";
public static final String EXTERNAL_TYPE = "externalType";
public static final String FACTORY_METHOD_ARGUMENT_TYPE = "factoryMethodArgumentType";
public static final String PRECISION = "precision";
public static final String SCALE = "scale";
public static final String CLASS_NAME = "className";
public static final String VALUE_CLASS_NAME = "valueClassName";
public static final String VALUE_FACTORY_CLASS_NAME = "valueFactoryClassName";
public static final String VALUE_FACTORY_METHOD_NAME = "valueFactoryMethodName";
public static final String VALUE_TYPE = "valueType";
public static final String DEFINITION = "definition";
public static final String WIDTH = "width";
public static final String DATA_TYPE = "dataType";
public static final String SERVER_TIME_ZONE = "serverTimeZone";
private String myName;
private String myColumnName;
private String myExternalType;
private String myValueType;
private String _className;
protected boolean _inferredClassName;
private String myValueClassName;
protected boolean _inferredValueClassName;
private String myValueFactoryClassName;
private String myValueFactoryMethodName;
private EOFactoryMethodArgumentType myFactoryMethodArgumentType;
private String myAdaptorValueConversionClassName;
private String myAdaptorValueConversionMethodName;
private Integer myScale;
private Integer myPrecision;
private Integer myWidth;
private Boolean myAllowsNull;
private String myDefinition;
private String myServerTimeZone;
private EOModelMap myArgumentMap;
private EODataType myDataType;
public AbstractEOArgument() {
myArgumentMap = new EOModelMap();
}
public AbstractEOArgument(String _name) {
this();
myName = _name;
}
public AbstractEOArgument(String _name, String _definition) {
this(_name);
myDefinition = _definition;
}
public void pasted() {
// DO NOTHING
}
protected abstract AbstractEOArgument _createArgument(String _name);
protected AbstractEOArgument _cloneArgument() {
AbstractEOArgument argument = _createArgument(myName);
_cloneIntoArgument(argument, false);
_cloneUserInfoInto(argument);
return argument;
}
public void _cloneIntoArgument(AbstractEOArgument argument, boolean updatingFlattenedAttribute) {
if (updatingFlattenedAttribute) {
argument.myColumnName = "";
} else {
argument.myColumnName = myColumnName;
}
argument.myExternalType = myExternalType;
argument.myValueType = myValueType;
argument.myValueClassName = myValueClassName;
argument._className = _className;
argument.myValueFactoryClassName = myValueFactoryClassName;
argument.myValueFactoryMethodName = myValueFactoryMethodName;
argument.myFactoryMethodArgumentType = myFactoryMethodArgumentType;
argument.myAdaptorValueConversionClassName = myAdaptorValueConversionClassName;
argument.myAdaptorValueConversionMethodName = myAdaptorValueConversionMethodName;
argument.myScale = myScale;
argument.myPrecision = myPrecision;
argument.myServerTimeZone = myServerTimeZone;
argument.myWidth = myWidth;
argument.myAllowsNull = myAllowsNull;
if (!updatingFlattenedAttribute) {
argument.myDefinition = myDefinition;
}
}
public boolean isFlattened() {
return StringUtils.isKeyPath(_getDefinition());
}
public void setName(String _name) throws DuplicateNameException {
setName(_name, true);
}
@SuppressWarnings("unused")
public void setName(String _name, boolean _fireEvents) throws DuplicateNameException {
String oldName = getName();
myName = _name;
if (_fireEvents) {
firePropertyChange(AbstractEOArgument.NAME, oldName, getName());
}
}
public String getName() {
return myName;
}
public Boolean getAllowsNull() {
return isAllowsNull();
}
public Boolean isAllowsNull() {
return myAllowsNull;
}
public void setAllowsNull(Boolean _allowsNull) {
_setAllowsNull(_allowsNull, true);
}
public void _setAllowsNull(Boolean _allowsNull, boolean _fireEvents) {
setAllowsNull(_allowsNull, _fireEvents);
}
public void setAllowsNull(Boolean _allowsNull, boolean _fireEvents) {
Boolean oldAllowsNull = getAllowsNull();
myAllowsNull = _allowsNull;
if (_fireEvents) {
firePropertyChange(AbstractEOArgument.ALLOWS_NULL, oldAllowsNull, getAllowsNull());
}
}
public String getColumnName() {
return myColumnName;
}
public void setColumnName(String _columnName) {
String oldColumnName = getColumnName();
myColumnName = _columnName;
firePropertyChange(AbstractEOArgument.COLUMN_NAME, oldColumnName, getColumnName());
}
public String getAdaptorValueConversionClassName() {
return myAdaptorValueConversionClassName;
}
public void setAdaptorValueConversionClassName(String _adaptorValueConversionClassName) {
String oldAdaptorValueConversionClassName = getAdaptorValueConversionClassName();
myAdaptorValueConversionClassName = _adaptorValueConversionClassName;
firePropertyChange(AbstractEOArgument.ADAPTOR_VALUE_CONVERSION_CLASS_NAME, oldAdaptorValueConversionClassName, getAdaptorValueConversionClassName());
}
public String getAdaptorValueConversionMethodName() {
return myAdaptorValueConversionMethodName;
}
public void setAdaptorValueConversionMethodName(String _adaptorValueConversionMethodName) {
String oldAdaptorValueConversionMethodName = getAdaptorValueConversionMethodName();
myAdaptorValueConversionMethodName = _adaptorValueConversionMethodName;
firePropertyChange(AbstractEOArgument.ADAPTOR_VALUE_CONVERSION_METHOD_NAME, oldAdaptorValueConversionMethodName, getAdaptorValueConversionMethodName());
}
public String getExternalType() {
return myExternalType;
}
public void setExternalType(String _externalType) {
String oldExternalType = getExternalType();
myExternalType = _externalType;
firePropertyChange(AbstractEOArgument.EXTERNAL_TYPE, oldExternalType, getExternalType());
}
public EOFactoryMethodArgumentType getFactoryMethodArgumentType() {
return myFactoryMethodArgumentType;
}
public void setFactoryMethodArgumentType(EOFactoryMethodArgumentType _factoryMethodArgumentType) {
EOFactoryMethodArgumentType oldFactoryMethodArgumentType = getFactoryMethodArgumentType();
myFactoryMethodArgumentType = _factoryMethodArgumentType;
firePropertyChange(AbstractEOArgument.FACTORY_METHOD_ARGUMENT_TYPE, oldFactoryMethodArgumentType, getFactoryMethodArgumentType());
}
public Integer getPrecision() {
return myPrecision;
}
public void setPrecision(Integer _precision) {
Integer oldPrecision = getPrecision();
myPrecision = _precision;
firePropertyChange(AbstractEOArgument.PRECISION, oldPrecision, getPrecision());
}
public Integer getScale() {
return myScale;
}
public void setScale(Integer _scale) {
Integer oldScale = getScale();
myScale = _scale;
firePropertyChange(AbstractEOArgument.SCALE, oldScale, getScale());
}
public String getServerTimeZone() {
return myServerTimeZone;
}
public void setServerTimeZone(String _serverTimeZone) {
String oldServerTimeZone = getServerTimeZone();
myServerTimeZone = _serverTimeZone;
firePropertyChange(AbstractEOArgument.SERVER_TIME_ZONE, oldServerTimeZone, getServerTimeZone());
}
public synchronized EODataType getDataType() {
EODataType dataType = myDataType;
if (dataType == null) {
if (getValueFactoryMethodName() != null || getAdaptorValueConversionMethodName() != null) {
dataType = EODataType.CUSTOM;
} else {
String className = _convertJavaClassNameToValueClassName(getClassName());
dataType = EODataType.getDataTypeByValueClassAndType(className, getValueType());
}
myDataType = dataType;
}
return dataType;
}
public void setDataType(EODataType _dataType) {
EODataType oldDataType = getDataType();
EODataType dataType = _dataType;
if (dataType == null) {
dataType = EODataType.CUSTOM;
}
setFactoryMethodArgumentType(null);
setAdaptorValueConversionMethodName(null);
// MS: I think clearing external type may be a little aggressive
// setExternalType(null);
setPrecision(null);
setScale(null);
setServerTimeZone(null);
setValueFactoryMethodName(null);
setWidth(null);
setValueClassName(dataType.getValueClass(), false);
setValueType(dataType.getFirstValueType(), false);
myDataType = dataType;
updateDataType(oldDataType);
}
protected void updateDataType(EODataType _oldDataType) {
EODataType dataType = getDataType();
firePropertyChange(AbstractEOArgument.DATA_TYPE, _oldDataType, dataType);
}
public String getJavaClassName() {
return getJavaClassName(true);
}
protected String _convertJavaClassNameToValueClassName(String javaClassName) {
String className = javaClassName;
if (className == null) {
className = null;
} else if (className.equals("java.lang.String")) {
className = "NSString";
} else if (className.equals("java.lang.Number") || className.equals("java.lang.Integer") || className.equals("java.lang.Long") || className.equals("java.lang.Short") || className.equals("java.lang.Double") || className.equals("java.lang.Float") || className.equals("java.lang.Byte")) {
className = "NSNumber";
} else if (className.equals("java.math.BigDecimal")) {
className = "NSDecimalNumber";
} else if (className.equals("com.webobjects.foundation.NSTimestamp")) {
className = "NSCalendarDate";
} else if (className.equals("com.webobjects.foundation.NSData")) {
className = "NSData";
} else if (className.equals("")) {
className = null;
} else {
//String[] strs = className.split("\\.");
//className = strs[strs.length - 1];
className = javaClassName;
}
return className;
}
public String getJavaClassName(boolean shorten) {
String className = getValueClassName();
if (shorten && className != null && className.startsWith("java.lang.")) {
className = className.substring("java.lang.".length());
}
if ("java.lang.Number".equals(className) || "Number".equals(className) || "NSNumber".equals(className)) {
String valueType = getValueType();
if (valueType == null || valueType.length() == 0) {
className = java.lang.Integer.class.getName();
} else if ("B".equals(valueType)) {
className = java.math.BigDecimal.class.getName();
} else if ("b".equals(valueType)) {
className = java.lang.Byte.class.getName();
} else if ("d".equals(valueType)) {
className = java.lang.Double.class.getName();
} else if ("f".equals(valueType)) {
className = java.lang.Float.class.getName();
} else if ("i".equals(valueType)) {
className = java.lang.Integer.class.getName();
} else if ("l".equals(valueType)) {
className = java.lang.Long.class.getName();
} else if ("s".equals(valueType)) {
className = java.lang.Short.class.getName();
} else if ("c".equals(valueType)) {
className = java.lang.Boolean.class.getName();
}
} else if ("NSString".equals(className)) {
className = java.lang.String.class.getName();
} else if ("NSCalendarDate".equals(className)) {
if (shorten) {
className = "NSTimestamp";
}
else {
className = "com.webobjects.foundation.NSTimestamp";
}
} else if ("NSDecimalNumber".equals(className)) {
String valueType = getValueType();
if (valueType == null || valueType.length() == 0) {
className = java.lang.Integer.class.getName();
} else {
className = java.math.BigDecimal.class.getName();
}
}
if (shorten && className != null && className.startsWith("java.lang.")) {
className = className.substring("java.lang.".length());
}
return className;
}
public String getClassName() {
return _className;
}
public void setClassName(String className) {
String oldClassName = getClassName();
_className = className;
_inferredClassName = false;
myDataType = null;
firePropertyChange(AbstractEOArgument.CLASS_NAME, oldClassName, getClassName());
// if (_updateDataType) {
// updateDataType(oldDataType);
// }
}
public String getValueClassName() {
return myValueClassName;
}
public void setValueClassName(String _valueClassName) {
setValueClassName(_valueClassName, true);
}
public synchronized void setValueClassName(String _valueClassName, boolean _updateDataType) {
EODataType oldDataType = getDataType();
String oldValueClassName = getValueClassName();
myValueClassName = _valueClassName;
_inferredValueClassName = false;
myDataType = null;
firePropertyChange(AbstractEOArgument.VALUE_CLASS_NAME, oldValueClassName, getValueClassName());
setClassName(getJavaClassName(false));
if (_updateDataType) {
updateDataType(oldDataType);
}
}
public String getValueFactoryClassName() {
return myValueFactoryClassName;
}
public void setValueFactoryClassName(String _valueFactoryClassName) {
String oldValueFactoryClassName = getValueFactoryClassName();
myValueFactoryClassName = _valueFactoryClassName;
firePropertyChange(AbstractEOArgument.VALUE_FACTORY_CLASS_NAME, oldValueFactoryClassName, getValueFactoryClassName());
}
public String getValueFactoryMethodName() {
return myValueFactoryMethodName;
}
public void setValueFactoryMethodName(String _valueFactoryMethodName) {
String oldValueFactoryMethodName = getValueFactoryMethodName();
myValueFactoryMethodName = _valueFactoryMethodName;
firePropertyChange(AbstractEOArgument.VALUE_FACTORY_METHOD_NAME, oldValueFactoryMethodName, getValueFactoryMethodName());
}
public String getValueType() {
return myValueType;
}
public void setValueType(String _valueType) {
setValueType(_valueType, false);
}
public synchronized void setValueType(String _valueType, boolean _updateDataType) {
EODataType oldDataType = getDataType();
String oldValueType = getValueType();
myValueType = _valueType;
myDataType = null;
firePropertyChange(AbstractEOArgument.VALUE_TYPE, oldValueType, getValueType());
if (_updateDataType) {
updateDataType(oldDataType);
}
setClassName(getJavaClassName(false));
}
public Integer getWidth() {
return myWidth;
}
public void setWidth(Integer _width) {
Integer oldWidth = getWidth();
myWidth = _width;
firePropertyChange(AbstractEOArgument.WIDTH, oldWidth, getWidth());
}
public void setDefinition(String _definition) {
String oldDefinition = myDefinition;
myDefinition = _definition;
updateDefinitionPath();
firePropertyChange(AbstractEOArgument.DEFINITION, oldDefinition, getDefinition());
}
public String getDefinition() {
return _getDefinition();
}
protected String _getDefinition() {
return myDefinition;
}
protected void updateDefinitionPath() {
// DO NOTHING
}
@SuppressWarnings("unused")
public void loadFromMap(EOModelMap _argumentMap, Set<EOModelVerificationFailure> _failures) {
myArgumentMap = _argumentMap;
myName = _argumentMap.getString("name", true);
if (_argumentMap.containsKey("externalName")) {
myColumnName = _argumentMap.getString("externalName", true);
} else {
myColumnName = _argumentMap.getString("columnName", true);
}
myExternalType = _argumentMap.getString("externalType", true);
myScale = _argumentMap.getInteger("scale");
myPrecision = _argumentMap.getInteger("precision");
if (_argumentMap.containsKey("maximumLength")) {
myWidth = _argumentMap.getInteger("maximumLength");
} else {
myWidth = _argumentMap.getInteger("width");
}
myValueType = _argumentMap.getString("valueType", true);
myValueClassName = _argumentMap.getString("valueClassName", true);
_className = _argumentMap.getString("className", true);
if (myValueClassName == null) {
myValueClassName = _convertJavaClassNameToValueClassName(_className);
_inferredValueClassName = true;
}
if (_className == null) {
_className = getJavaClassName(false);
_inferredClassName = true;
}
myValueFactoryClassName = _argumentMap.getString("valueFactoryClassName", true);
myValueFactoryMethodName = _argumentMap.getString("valueFactoryMethodName", true);
myFactoryMethodArgumentType = EOFactoryMethodArgumentType.getFactoryMethodArgumentTypeByID(_argumentMap.getString("factoryMethodArgumentType", true));
myAdaptorValueConversionClassName = _argumentMap.getString("adaptorValueConversionClassName", true);
myAdaptorValueConversionMethodName = _argumentMap.getString("adaptorValueConversionMethodName", true);
myServerTimeZone = _argumentMap.getString("serverTimeZone", true);
myAllowsNull = _argumentMap.getBoolean("allowsNull");
myDefinition = _argumentMap.getString("definition", true);
loadUserInfo(_argumentMap);
}
public EOModelMap toMap() {
EOModelMap argumentMap = myArgumentMap.cloneModelMap();
argumentMap.setString("name", getName(), true);
// If columnName is prototyped, EOModeler leaves out the columnName. If,
// however, columnName is MISSING, then it needs to write a "".
if (isFlattened()) {
argumentMap.remove("columnName");
} else if (myColumnName == null && getColumnName() == null) {
argumentMap.setString("columnName", "", false);
} else {
argumentMap.setString("columnName", myColumnName, false);
}
argumentMap.remove("externalName");
argumentMap.setString("externalType", myExternalType, true);
argumentMap.setInteger("scale", myScale);
argumentMap.setInteger("precision", myPrecision);
argumentMap.setInteger("width", myWidth);
argumentMap.setString("serverTimeZone", myServerTimeZone, true);
argumentMap.remove("maximumLength");
argumentMap.setString("valueType", myValueType, true);
boolean usesClassNameProperty = !ComparisonUtils.equals(getJavaClassName(false), getClassName());
if (usesClassNameProperty) {
argumentMap.setString("className", _className, true);
String convertedValueClassName = _convertJavaClassNameToValueClassName(_className);
// MS: If we guess the same value class name as you have now, just go ahead and leave it. If they don't
// match, assume you typed in an explicit class name and let's toss the old value class name
if (!ComparisonUtils.equals(convertedValueClassName, myValueClassName)) {
argumentMap.remove("valueClassName");
}
} else {
argumentMap.remove("className");
argumentMap.setString("valueClassName", myValueClassName, true);
}
argumentMap.setString("valueFactoryClassName", myValueFactoryClassName, true);
argumentMap.setString("valueFactoryMethodName", myValueFactoryMethodName, true);
if (myFactoryMethodArgumentType != null) {
argumentMap.setString("factoryMethodArgumentType", myFactoryMethodArgumentType.getID(), true);
} else {
argumentMap.remove("factoryMethodArgumentType");
}
argumentMap.setString("adaptorValueConversionClassName", myAdaptorValueConversionClassName, true);
argumentMap.setString("adaptorValueConversionMethodName", myAdaptorValueConversionMethodName, true);
if (isPrototyped()) {
argumentMap.setBoolean("allowsNull", myAllowsNull, EOModelMap.YN);
} else {
argumentMap.setBoolean("allowsNull", myAllowsNull, EOModelMap.YNOptionalDefaultNo);
}
argumentMap.setString("definition", myDefinition, true);
writeUserInfo(argumentMap);
return argumentMap;
}
protected boolean isPrototyped() {
return false;
}
public EOModelMap getArgumentMap() {
return myArgumentMap;
}
public String toString() {
return "[EOArgument: " + myName + "]";
}
}