blob: 5e1b4696c4acba78ab17a130c00393ce658edfd9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.openjpa.persistence;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.persistence.CacheRetrieveMode;
import javax.persistence.CacheStoreMode;
import org.apache.openjpa.lib.util.StringUtil;
import org.apache.openjpa.kernel.DataCacheRetrieveMode;
import org.apache.openjpa.kernel.DataCacheStoreMode;
/**
* Enumerates configuration property keys defined in JPA 2.0 Specification.
* <br>
* Provides static utility functions to read their values from supplied map of properties.
* <br>
* Provides static utility functions to convert them to values that are fit for OpenJPA implementation.
* <br>
* @author Pinaki Poddar
* @since 2.0.0
*
*/
public class JPAProperties {
private static final String REGEX_DOT = "\\.";
public static final String PREFIX = "javax.persistence.";
public static final String PROVIDER = PREFIX + "provider";
public static final String TRANSACTION_TYPE = PREFIX + "transactionType";
public static final String DATASOURCE = PREFIX + "dataSource";
public static final String DATASOURCE_JTA = PREFIX + "jtaDataSource";
public static final String DATASOURCE_NONJTA = PREFIX + "nonJtaDataSource";
public static final String JDBC_DRIVER = PREFIX + "jdbc.driver";
public static final String JDBC_URL = PREFIX + "jdbc.url";
public static final String JDBC_USER = PREFIX + "jdbc.user";
public static final String JDBC_PASSWORD = PREFIX + "jdbc.password";
public static final String LOCK_SCOPE = PREFIX + "lock.scope";
public static final String LOCK_TIMEOUT = PREFIX + "lock.timeout";
public static final String QUERY_TIMEOUT = PREFIX + "query.timeout";
public static final String CACHE_MODE = PREFIX + "sharedCache.mode";
public static final String CACHE_STORE_MODE = PREFIX + "cache.storeMode";
public static final String CACHE_RETRIEVE_MODE = PREFIX + "cache.retrieveMode";
public static final String VALIDATE_FACTORY = PREFIX + "validation.factory";
public static final String VALIDATE_MODE = PREFIX + "validation.mode";
public static final String VALIDATE_PRE_PERSIST = PREFIX + "validation.group.pre-persist";
public static final String VALIDATE_PRE_REMOVE = PREFIX + "validation.group.pre-remove";
public static final String VALIDATE_PRE_UPDATE = PREFIX + "validation.group.pre-update";
public static final String VALIDATE_GROUP_DEFAULT = "javax.validation.groups.Default";
private static Map<String,String> _names = new HashMap<String, String>();
/**
* Record the given kernel property key (which is a bean property name without any suffix)
* corresponding to the given original JPA/OpenJPA property used by the user to set the values.
*/
static void record(String kernel, String user) {
_names.put(kernel, user);
}
/**
* Gets the original JPA Property name corresponding to the kernel property key
* (which is a bean property name without any suffix).
*/
static String getUserName(String beanProperty) {
return _names.containsKey(beanProperty) ? _names.get(beanProperty) : beanProperty;
}
/**
* Is the given key appears to be a valid JPA specification defined key?
*
* @return true if the given string merely prefixed with <code>javax.persistence.</code>.
* Does not really check all the keys defined in the specification.
*/
public static boolean isValidKey(String key) {
return key != null && key.startsWith(PREFIX);
}
/**
* Gets a bean-style property name from the given key.
*
* @param key must begin with JPA property prefix <code>javax.persistence</code>
*
* @return concatenates each part of the string leaving out <code>javax.persistence.</code> prefix.
* Part of string is what appears between DOT character.
*/
public static String getBeanProperty(String key) {
if (!isValidKey(key))
throw new IllegalArgumentException("Invalid JPA property " + key);
String[] parts = key.split(REGEX_DOT);
StringBuilder buf = new StringBuilder();
for (int i = 2; i < parts.length; i++) {
buf.append(StringUtil.capitalize(parts[i]));
}
return buf.toString();
}
/**
* Convert the given user value to a value consumable by OpenJPA kernel constructs.
*
* @return the same value if the given key is not a valid JPA property key or the value is null.
*/
public static <T> T convertToKernelValue(Class<T> resultType, String key, Object value) {
if (value == null)
return null;
if (JPAProperties.isValidKey(key)) {
// works because enum values are identical String
if (value instanceof CacheRetrieveMode || (value instanceof String && CACHE_RETRIEVE_MODE.equals(key))) {
return (T)DataCacheRetrieveMode.valueOf(value.toString().trim().toUpperCase(Locale.ENGLISH));
} else if (value instanceof CacheStoreMode || (value instanceof String && CACHE_STORE_MODE.equals(key))) {
return (T)DataCacheStoreMode.valueOf(value.toString().trim().toUpperCase(Locale.ENGLISH));
}
}
return (T)value;
}
/**
* Convert the given kernel value to a value visible to the user.
*
* @return the same value if the given key is not a valid JPA property key or the value is null.
*/
public static Object convertToUserValue(String key, Object value) {
if (value == null)
return null;
if (JPAProperties.isValidKey(key)) {
// works because enum values are identical String
if (value instanceof DataCacheRetrieveMode) {
return CacheRetrieveMode.valueOf(value.toString().trim().toUpperCase(Locale.ENGLISH));
} else if (value instanceof DataCacheStoreMode) {
return CacheStoreMode.valueOf(value.toString().trim().toUpperCase(Locale.ENGLISH));
}
}
return value;
}
/**
* Get the value of the given key from the given properties after converting it to the given
* enumerated value.
*/
public static <E extends Enum<E>> E getEnumValue(Class<E> type, String key, Map<String,Object> prop) {
return getEnumValue(type, null, key, prop);
}
/**
* Gets a enum value of the given type from the given properties looking up with the given key.
* Converts the original value from a String or ordinal number, if necessary.
* Conversion from an integral number to enum value is only attempted if the allowed enum values
* are provided as non-null, non-empty array.
*
* @return null if the key does not exist in the given properties.
*/
public static <E extends Enum<E>> E getEnumValue(Class<E> type, E[] values, String key, Map<String,Object> prop) {
if (prop == null)
return null;
return getEnumValue(type, values, prop.get(key));
}
/**
* Gets a enum value of the given type from the given value.
* Converts the original value from a String, if necessary.
*
* @return null if the key does not exist in the given properties.
*/
public static <E extends Enum<E>> E getEnumValue(Class<E> type, Object val) {
return getEnumValue(type, null, val);
}
/**
* Gets a enum value of the given type from the given value.
* Converts the original value from a String or ordinal number, if necessary.
* Conversion from an integral number to enum value is only attempted if the allowed enum values
* are provided as non-null, non-empty array.
*
* @return null if the key does not exist in the given properties.
*/
public static <E extends Enum<E>> E getEnumValue(Class<E> type, E[] values, Object val) {
if (val == null)
return null;
if (type.isInstance(val))
return (E)val;
if (val instanceof String) {
return Enum.valueOf(type, val.toString().trim().toUpperCase(Locale.ENGLISH));
}
if (values != null && values.length > 0 && val instanceof Number) {
return values[((Number)val).intValue()];
}
return null;
}
}