org.eclipse.persistence.mappings.converters.EnumTypeConverter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.persistence.core Show documentation
Show all versions of org.eclipse.persistence.core Show documentation
EclipseLink build based upon Git transaction ecdf3c32c4
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
// // 30/05/2012-2.4 Guy Pelletier
// - 354678: Temp classloader is still being used during metadata processing
package org.eclipse.persistence.mappings.converters;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.EnumSet;
import java.util.Iterator;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.sessions.Session;
/**
* Purpose: Object type converter is used to match a fixed number of
* database data values to a Java enum object value. It can be used when the
* values on the database and in the Java differ. To create an object type
* converter, simply specify the set of conversion value pairs. A default value
* and one-way conversion are also supported for legacy data situations.
*
* @author Guy Pelletier
* @since Toplink 10.1.4RI
*/
public class EnumTypeConverter extends ObjectTypeConverter {
private Class m_enumClass;
private String m_enumClassName;
private boolean m_useOrdinalValues;
/**
* PUBLIC:
* Creating an enum converter this way will create the conversion values
* for you using ordinal or name values.
*/
public EnumTypeConverter(DatabaseMapping mapping, Class enumClass, boolean useOrdinalValues) {
super(mapping);
m_enumClass = enumClass;
m_enumClassName = enumClass.getName();
m_useOrdinalValues = useOrdinalValues;
initializeConversions(m_enumClass);
}
/**
* PUBLIC:
* Creating an enum converter this way will create the conversion values
* for you using ordinal or name values.
*/
public EnumTypeConverter(DatabaseMapping mapping, String enumClassName, boolean useOrdinalValues) {
this(mapping, enumClassName);
m_useOrdinalValues = useOrdinalValues;
}
/**
* PUBLIC:
* Creating an enum converter this way expects that you will provide
* the conversion values separately.
*/
public EnumTypeConverter(DatabaseMapping mapping, String enumClassName) {
super(mapping);
m_enumClassName = enumClassName;
}
protected void initializeConversions(Class enumClass) {
// Initialize conversion if not already set by Converter
if (getFieldToAttributeValues().isEmpty()) {
EnumSet theEnums = EnumSet.allOf(enumClass);
Iterator i = theEnums.iterator();
while (i.hasNext()) {
Enum theEnum = i.next();
if (m_useOrdinalValues) {
addConversionValue(theEnum.ordinal(), theEnum.name());
} else {
addConversionValue(theEnum.name(), theEnum.name());
}
}
}
}
public Class getEnumClass() {
return m_enumClass;
}
public String getEnumClassName() {
return m_enumClassName;
}
/**
* INTERNAL:
* Convert all the class-name-based settings in this converter to actual
* class-based settings. This method is used when converting a project
* that has been built with class names to a project with classes.
* @param classLoader
*/
@Override
public void convertClassNamesToClasses(ClassLoader classLoader) {
super.convertClassNamesToClasses(classLoader);
// convert if enumClass is null or if different classLoader
if (m_enumClass == null || !m_enumClass.getClassLoader().equals(classLoader)) {
try {
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
m_enumClass = AccessController.doPrivileged(
new PrivilegedClassForName(m_enumClassName, true, classLoader));
} catch (PrivilegedActionException exception) {
throw ValidationException.classNotFoundWhileConvertingClassNames(
m_enumClassName, exception.getException());
}
} else {
m_enumClass = PrivilegedAccessHelper.getClassForName(m_enumClassName, true,
classLoader);
}
} catch (ClassNotFoundException exception){
throw ValidationException.classNotFoundWhileConvertingClassNames(m_enumClassName,
exception);
}
}
initializeConversions(m_enumClass);
}
/**
* INTERNAL:
* Returns the corresponding attribute value for the specified field value.
* Wraps the super method to return an Enum type from the string conversion.
*/
@Override
public Object convertDataValueToObjectValue(Object fieldValue, Session session) {
Object obj = super.convertDataValueToObjectValue(fieldValue, session);
if (fieldValue == null || obj == null) {
return obj;
} else {
return Enum.valueOf(m_enumClass, (String) obj);
}
}
/**
* INTERNAL:
* Convert Enum object to the data value. Internal enums are stored as
* strings (names) so this method wraps the super method in that if
* breaks down the enum to a string name before converting it.
*/
@Override
public Object convertObjectValueToDataValue(Object attributeValue, Session session) {
if (attributeValue == null) {
return super.convertObjectValueToDataValue(null, session);
} else {
return super.convertObjectValueToDataValue(((Enum)attributeValue).name(), session);
}
}
}