Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.impetus.kundera.metadata.MetadataUtils Maven / Gradle / Ivy
/*******************************************************************************
* * Copyright 2012 Impetus Infotech.
* *
* * 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.impetus.kundera.metadata;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.PersistenceException;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;
import javax.validation.constraints.AssertFalse;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.apache.commons.lang.StringUtils;
import com.impetus.kundera.Constants;
import com.impetus.kundera.PersistenceProperties;
import com.impetus.kundera.index.IndexCollection;
import com.impetus.kundera.metadata.model.ClientMetadata;
import com.impetus.kundera.metadata.model.EntityMetadata;
import com.impetus.kundera.metadata.model.MetamodelImpl;
import com.impetus.kundera.metadata.model.PersistenceUnitMetadata;
import com.impetus.kundera.metadata.model.Relation;
import com.impetus.kundera.metadata.model.Relation.ForeignKey;
import com.impetus.kundera.metadata.model.attributes.AbstractAttribute;
import com.impetus.kundera.metadata.validator.InvalidEntityDefinitionException;
import com.impetus.kundera.persistence.EntityManagerFactoryImpl.KunderaMetadata;
import com.impetus.kundera.property.PropertyAccessorHelper;
/**
* Utility class for entity metadata related funcntionality.
*
* @author amresh.singh
*/
public class MetadataUtils
{
/**
* Populate column and super column maps.
*
* @param m
* the m
* @param columnNameToFieldMap
* the column name to field map
* @param superColumnNameToFieldMap
* the super column name to field map
*/
public static void populateColumnAndSuperColumnMaps(EntityMetadata m, Map columnNameToFieldMap,
Map superColumnNameToFieldMap, final KunderaMetadata kunderaMetadata)
{
getEmbeddableType(m, columnNameToFieldMap, superColumnNameToFieldMap, kunderaMetadata);
}
/**
* Creates the columns field map.
*
* @param m
* the m
* @param superColumn
* the super column
* @return the map
*/
public static Map createColumnsFieldMap(EntityMetadata m, EmbeddableType superColumn)
{
Map columnNameToFieldMap = new HashMap();
Set attributes = superColumn.getAttributes();
for (Attribute column : attributes)
{
columnNameToFieldMap.put(((AbstractAttribute) column).getJPAColumnName(), (Field) column.getJavaMember());
}
return columnNameToFieldMap;
}
/**
* Creates the super columns field map.
*
* @param m
* the m
* @return the map
*/
public static Map createSuperColumnsFieldMap(final EntityMetadata m,
final KunderaMetadata kunderaMetadata)
{
Map superColumnNameToFieldMap = new HashMap();
getEmbeddableType(m, null, superColumnNameToFieldMap, kunderaMetadata);
return superColumnNameToFieldMap;
}
/**
* Gets the embedded collection instance.
*
* @param embeddedCollectionField
* the embedded collection field
* @return the embedded collection instance
*/
public static Collection getEmbeddedCollectionInstance(Field embeddedCollectionField)
{
Collection embeddedCollection = null;
Class embeddedCollectionFieldClass = embeddedCollectionField.getType();
if (embeddedCollection == null || embeddedCollection.isEmpty())
{
if (embeddedCollectionFieldClass.equals(List.class))
{
embeddedCollection = new ArrayList();
}
else if (embeddedCollectionFieldClass.equals(Set.class))
{
embeddedCollection = new HashSet();
}
else
{
throw new InvalidEntityDefinitionException("Field " + embeddedCollectionField.getName()
+ " must be either instance of List or Set");
}
}
return embeddedCollection;
}
/**
* Gets the embedded generic object instance.
*
* @param embeddedCollectionField
* the embedded collection field
* @return the embedded generic object instance
*/
public static Object getEmbeddedGenericObjectInstance(Field embeddedCollectionField)
{
Class> embeddedClass = PropertyAccessorHelper.getGenericClass(embeddedCollectionField);
Object embeddedObject = null;
// must have a default no-argument constructor
try
{
embeddedClass.getConstructor();
embeddedObject = embeddedClass.newInstance();
}
catch (NoSuchMethodException nsme)
{
throw new PersistenceException(embeddedClass.getName()
+ " is @Embeddable and must have a default no-argument constructor.");
}
catch (InstantiationException e)
{
throw new PersistenceException(embeddedClass.getName() + " could not be instantiated");
}
catch (IllegalAccessException e)
{
throw new PersistenceException(embeddedClass.getName() + " could not be accessed");
}
return embeddedObject;
}
/**
* Gets the embedded collection prefix.
*
* @param embeddedCollectionName
* the embedded collection name
* @return the embedded collection prefix
*/
public static String getEmbeddedCollectionPrefix(String embeddedCollectionName)
{
return embeddedCollectionName.substring(0,
embeddedCollectionName.indexOf(Constants.EMBEDDED_COLUMN_NAME_DELIMITER));
}
/**
* Gets the embedded collection postfix.
*
* @param embeddedCollectionName
* the embedded collection name
* @return the embedded collection postfix
*/
public static String getEmbeddedCollectionPostfix(String embeddedCollectionName)
{
return embeddedCollectionName.substring(
embeddedCollectionName.lastIndexOf(Constants.EMBEDDED_COLUMN_NAME_DELIMITER) + 1,
embeddedCollectionName.length());
}
/**
* Creates a string representation of a set of foreign keys by combining
* them together separated by "~" character.
*
* Note: Assumption is that @Id will never contain "~" character. Checks for
* this are not added yet.
*
* @param foreignKeys
* the foreign keys
* @return the string
*/
public static String serializeKeys(Set foreignKeys)
{
if (null == foreignKeys || foreignKeys.isEmpty())
{
return null;
}
StringBuilder sb = new StringBuilder();
for (String key : foreignKeys)
{
if (sb.length() > 0)
{
sb.append(Constants.FOREIGN_KEY_SEPARATOR);
}
sb.append(key);
}
return sb.toString();
}
/**
* Splits foreign keys into Set.
*
* @param foreignKeys
* the foreign keys
* @return the set
*/
public static Set deserializeKeys(String foreignKeys)
{
Set keys = new HashSet();
if (null == foreignKeys || foreignKeys.isEmpty())
{
return keys;
}
String array[] = foreignKeys.split(Constants.FOREIGN_KEY_SEPARATOR);
for (String element : array)
{
keys.add(element);
}
return keys;
}
/**
* Sets the schema and persistence unit.
*
* @param m
* the m
* @param schemaStr
* the schema str
* @param puProperties
*/
public static void setSchemaAndPersistenceUnit(EntityMetadata m, String schemaStr, Map puProperties)
{
if (schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR) > 0)
{
String schemaName = null;
if (puProperties != null)
{
schemaName = (String) puProperties.get(PersistenceProperties.KUNDERA_KEYSPACE);
}
if (schemaName == null)
{
schemaName = schemaStr.substring(0, schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR));
}
m.setSchema(schemaName);
m.setPersistenceUnit(schemaStr.substring(
schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR) + 1, schemaStr.length()));
}
else
{
m.setSchema(StringUtils.isBlank(schemaStr) ? null : schemaStr);
}
}
/**
* Returns true, if use of secondry index is available, else false.
*
* @param persistenceUnit
* persistence unit name
* @return true, if usage is true in pu. else false.
*/
public static boolean useSecondryIndex(ClientMetadata clientMetadata)
{
return clientMetadata != null ? clientMetadata.isUseSecondryIndex() : false;
}
/* *//**
* Returns lucene indexing directory.
*
* @param persistenceUnit
* persistence unit name
* @return lucene directory
*/
/*
* public static String getLuceneDirectory(String persistenceUnit) { if
* (!useSecondryIndex(persistenceUnit)) { ClientMetadata clientMetadata =
* kunderaMetadata.getClientMetadata(persistenceUnit); return
* clientMetadata.getLuceneIndexDir(); }
*
* return null; }
*/
/**
* Returns mapped relational name, in case of bi directional mapping, it
* will return back pKey name of associated entity.
*
* @param relation
* holding relation.
* @return mapped/join column name.
*/
public static String getMappedName(EntityMetadata parentMetadata, Relation relation,
final KunderaMetadata kunderaMetadata)
{
if (relation != null)
{
String joinColumn = relation.getJoinColumnName(kunderaMetadata);
if (joinColumn == null)
{
Class clazz = relation.getTargetEntity();
EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, clazz);
joinColumn = relation.getType().equals(ForeignKey.ONE_TO_MANY) ? ((AbstractAttribute) parentMetadata
.getIdAttribute()).getJPAColumnName() : ((AbstractAttribute) metadata.getIdAttribute())
.getJPAColumnName();
}
return joinColumn;
}
return null;
}
/**
* Gets the enclosing document name.
*
* @param m
* the m
* @param criteria
* Input criteria
* @param viaColumnName
* true if criteria
is column Name, false if
* criteria
is column field name
* @return the enclosing document name
*/
public static String getEnclosingEmbeddedFieldName(EntityMetadata m, String criteria, boolean viaColumnName,
final KunderaMetadata kunderaMetadata)
{
String enclosingEmbeddedFieldName = null;
StringTokenizer strToken = new StringTokenizer(criteria, ".");
String embeddableAttributeName = null;
String embeddedFieldName = null;
String nestedEmbeddedFieldName = null;
if (strToken.countTokens() > 0)
{
embeddableAttributeName = strToken.nextToken();
}
if (strToken.countTokens() > 0)
{
embeddedFieldName = strToken.nextToken();
}
if (strToken.countTokens() > 0)
{
nestedEmbeddedFieldName = strToken.nextToken();
}
Metamodel metaModel = kunderaMetadata.getApplicationMetadata().getMetamodel(m.getPersistenceUnit());
EntityType entity = metaModel.entity(m.getEntityClazz());
try
{
Attribute attribute = entity.getAttribute(embeddableAttributeName);
if (((MetamodelImpl) metaModel).isEmbeddable(((AbstractAttribute) attribute).getBindableJavaType()))
{
EmbeddableType embeddable = metaModel.embeddable(((AbstractAttribute) attribute).getBindableJavaType());
Iterator attributeIter = embeddable.getAttributes().iterator();
while (attributeIter.hasNext())
{
AbstractAttribute attrib = (AbstractAttribute) attributeIter.next();
if (viaColumnName && attrib.getName().equals(embeddedFieldName))
{
if (nestedEmbeddedFieldName != null
&& ((MetamodelImpl) metaModel).isEmbeddable(((AbstractAttribute) attrib)
.getBindableJavaType()))
{
EmbeddableType nestedEmbeddable = metaModel.embeddable(((AbstractAttribute) attrib)
.getBindableJavaType());
Iterator iter = embeddable.getAttributes().iterator();
while (iter.hasNext())
{
AbstractAttribute nestedAttribute = (AbstractAttribute) iter.next();
if (viaColumnName && nestedAttribute.getName().equals(embeddedFieldName))
{
return nestedAttribute.getName();
}
if (!viaColumnName && nestedAttribute.getJPAColumnName().equals(embeddedFieldName))
{
return nestedAttribute.getName();
}
}
}
else if (nestedEmbeddedFieldName != null
&& !((MetamodelImpl) metaModel).isEmbeddable(((AbstractAttribute) attrib)
.getBindableJavaType()))
{
return null;
}
else
{
return attribute.getName();
}
}
if (!viaColumnName && attrib.getJPAColumnName().equals(embeddedFieldName))
{
return attribute.getName();
}
}
}
}
catch (IllegalArgumentException iax)
{
return null;
}
return enclosingEmbeddedFieldName;
}
private static void getEmbeddableType(EntityMetadata m, Map columnNameToFieldMap,
Map superColumnNameToFieldMap, final KunderaMetadata kunderaMetadata)
{
Metamodel metaModel = kunderaMetadata.getApplicationMetadata().getMetamodel(m.getPersistenceUnit());
EntityType entityType = metaModel.entity(m.getEntityClazz());
Set attributes = entityType.getAttributes();
Iterator iter = attributes.iterator();
while (iter.hasNext())
{
Attribute attribute = iter.next();
if (((MetamodelImpl) metaModel).isEmbeddable(((AbstractAttribute) attribute).getBindableJavaType()))
{
superColumnNameToFieldMap.put(((AbstractAttribute) attribute).getJPAColumnName(),
(Field) attribute.getJavaMember());
if (columnNameToFieldMap != null)
{
getAttributeOfEmbedddable(columnNameToFieldMap, metaModel, attribute);
}
}
else
{
if (columnNameToFieldMap != null)
{
columnNameToFieldMap.put(((AbstractAttribute) attribute).getJPAColumnName(),
(Field) attribute.getJavaMember());
}
}
}
}
private static void getAttributeOfEmbedddable(Map columnNameToFieldMap, Metamodel metaModel,
Attribute attribute)
{
EmbeddableType embeddable = metaModel.embeddable(((AbstractAttribute) attribute).getBindableJavaType());
Iterator embeddableIter = embeddable.getAttributes().iterator();
while (embeddableIter.hasNext())
{
Attribute embedAttrib = embeddableIter.next();
// Reason is to avoid in case embeddable attribute within
// embeddable.
if (!((MetamodelImpl) metaModel).isEmbeddable(embedAttrib.getJavaType()))
{
columnNameToFieldMap.put(((AbstractAttribute) embedAttrib).getJPAColumnName(),
(Field) embedAttrib.getJavaMember());
}
else
{
getAttributeOfEmbedddable(columnNameToFieldMap, metaModel, embedAttrib);
}
}
}
public static boolean isEmbeddedAtributeIndexable(Field embeddedField)
{
Class> embeddableClass = PropertyAccessorHelper.getGenericClass(embeddedField);
IndexCollection indexCollection = embeddableClass.getAnnotation(IndexCollection.class);
if (indexCollection != null && indexCollection.columns() != null)
{
return true;
}
return false;
}
public static boolean isColumnInEmbeddableIndexable(Field embeddedField, String columnFieldName)
{
Class> embeddableClass = PropertyAccessorHelper.getGenericClass(embeddedField);
IndexCollection indexCollection = embeddableClass.getAnnotation(IndexCollection.class);
if (indexCollection != null && indexCollection.columns() != null)
{
for (com.impetus.kundera.index.Index column : indexCollection.columns())
{
if (columnFieldName != null && column != null && column.name() != null
&& column.name().equals(columnFieldName))
{
return true;
}
}
}
return false;
}
/**
* If client specific to parameterized persistence unit does not support
* transaction, return true else will return false.
*
* @param persistenceUnit
* @return
*/
public static boolean defaultTransactionSupported(final String persistenceUnit,
final KunderaMetadata kunderaMetadata)
{
PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(kunderaMetadata,
persistenceUnit);
String txResource = puMetadata.getProperty(PersistenceProperties.KUNDERA_TRANSACTION_RESOURCE);
if (txResource == null)
{
return true;
}
else if (txResource.isEmpty())
{
throw new IllegalArgumentException("Property " + PersistenceProperties.KUNDERA_TRANSACTION_RESOURCE
+ " is blank");
}
else
{
return false;
}
}
public static boolean isSchemaAttributeRequired(final String persistenceUnit, final KunderaMetadata kunderaMetadata)
{
PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(kunderaMetadata,
persistenceUnit);
String clientFactoryName = puMetadata != null ? puMetadata
.getProperty(PersistenceProperties.KUNDERA_CLIENT_FACTORY) : null;
return !(Constants.NEO4J_CLIENT_FACTORY.equalsIgnoreCase(clientFactoryName) || Constants.RDBMS_CLIENT_FACTORY
.equalsIgnoreCase(clientFactoryName));
}
/**
* Index based search has to be optional, ideally need to register a
* callback in case index persistence/search etc is optional.
*
* @param persistenceUnit
* persistence unit
*
* @return true, if index based search is enabled.
*/
public static boolean indexSearchEnabled(final String persistenceUnit, final KunderaMetadata kunderaMetadata)
{
PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(kunderaMetadata,
persistenceUnit);
String clientFactoryName = puMetadata != null ? puMetadata
.getProperty(PersistenceProperties.KUNDERA_CLIENT_FACTORY) : null;
return !(Constants.REDIS_CLIENT_FACTORY.equalsIgnoreCase(clientFactoryName));
}
/**
* Checks whether a given field is Element collection field of BASIC type
*
* @param collectionField
* @return
*/
public static boolean isBasicElementCollectionField(Field collectionField)
{
if (!Collection.class.isAssignableFrom(collectionField.getType())
&& !Map.class.isAssignableFrom(collectionField.getType()))
{
return false;
}
List> genericClasses = PropertyAccessorHelper.getGenericClasses(collectionField);
for (Class genericClass : genericClasses)
{
if (genericClass.getAnnotation(Embeddable.class) != null)
{
return false;
}
}
return true;
}
/**
* Checks whether an entity with given metadata contains a collection field
*
* @param m
* @return
*/
public static boolean containsBasicElementCollectionField(final EntityMetadata m,
final KunderaMetadata kunderaMetadata)
{
Metamodel metaModel = kunderaMetadata.getApplicationMetadata().getMetamodel(m.getPersistenceUnit());
EntityType entityType = metaModel.entity(m.getEntityClazz());
Iterator iter = entityType.getAttributes().iterator();
while (iter.hasNext())
{
Attribute attr = iter.next();
if (attr.isCollection() && !attr.isAssociation()
&& isBasicElementCollectionField((Field) attr.getJavaMember()))
{
return true;
}
}
return false;
}
public static void onJPAColumnMapping(final EntityType entityType, EntityMetadata entityMetadata)
{
Set attributes = entityType.getAttributes();
Iterator iter = attributes.iterator();
while (iter.hasNext())
{
Attribute attribute = iter.next();
// jpa column mapping is for non id columns only.
if (!entityMetadata.getIdAttribute().equals(attribute))
{
entityMetadata.addJPAColumnMapping(((AbstractAttribute) attribute).getJPAColumnName(),
attribute.getName());
}
}
entityMetadata.setEntityType(entityType);
}
/**
* Returns true if an entity contains attributes with validation constraints
* enabled
*
* @param attribute
* @return
*/
public static boolean onCheckValidationConstraints(Field attribute)
{
// / Checks if attribute contains any validation constraint enabled
return attribute.isAnnotationPresent(AssertFalse.class) || attribute.isAnnotationPresent(AssertTrue.class)
|| attribute.isAnnotationPresent(DecimalMax.class) || attribute.isAnnotationPresent(DecimalMin.class)
|| attribute.isAnnotationPresent(Digits.class) || attribute.isAnnotationPresent(Future.class)
|| attribute.isAnnotationPresent(Max.class) || attribute.isAnnotationPresent(Min.class)
|| attribute.isAnnotationPresent(NotNull.class) || attribute.isAnnotationPresent(Null.class)
|| attribute.isAnnotationPresent(Past.class) || attribute.isAnnotationPresent(Pattern.class)
|| attribute.isAnnotationPresent(Size.class);
}
/**
* Returns true if an entity contains embedded attribute
* enabled
*
* @param attribute
* @return
*/
public static boolean onCheckEmbeddableAttribute(Field attribute)
{
// / Checks if attribute is embeddable
return attribute.isAnnotationPresent(Embedded.class) ;
}
}