
com.vaadin.addon.jpacontainer.metadata.ClassMetadata Maven / Gradle / Ivy
The newest version!
/*
* JPAContainer
* Copyright (C) 2010 Oy IT Mill Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package com.vaadin.addon.jpacontainer.metadata;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.StringTokenizer;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
/**
* This class provides a way of accessing the JPA mapping metadata of
* {@link Entity} and {@link Embeddable} classes. This information may be used
* to construct queries or decide whether a property is sortable or not.
*
* @see EntityClassMetadata
* @author Petter Holmström (IT Mill)
* @since 1.0
*/
public class ClassMetadata implements Serializable {
private static final long serialVersionUID = 2569781449737488799L;
private final Class mappedClass;
private final Map allProperties = new LinkedHashMap();
private final Map persistentProperties = new LinkedHashMap();
/**
* Constructs a new ClassMetadata
instance. Properties can be
* added using the
* {@link #addProperties(com.vaadin.addons.jpacontainer.metadata.PropertyMetadata[]) }
* method.
*
* @param mappedClass
* the mapped class (must not be null).
*/
ClassMetadata(Class mappedClass) {
assert mappedClass != null : "mappedClass must not be null";
this.mappedClass = mappedClass;
}
/**
* Adds the specified property metadata to the class. Any existing
* properties with the same names will be overwritten.
*
* @param properties
* an array of properties to add.
*/
final void addProperties(PropertyMetadata... properties) {
assert properties != null : "properties must not be null";
for (PropertyMetadata pm : properties) {
allProperties.put(pm.getName(), pm);
if (pm instanceof PersistentPropertyMetadata) {
persistentProperties.put(pm.getName(),
(PersistentPropertyMetadata) pm);
} else {
// If we have a previous property and want to overwrite
// it with another that is not persistent
persistentProperties.remove(pm.getName());
}
}
}
/**
* Gets the mapped class.
*
* @return the class (never null).
*/
public Class getMappedClass() {
return mappedClass;
}
/**
* Gets all the persistent properties of the class.
*
* @return an unmodifiable collection of property metadata.
*/
public Collection getPersistentProperties() {
return Collections
.unmodifiableCollection(persistentProperties.values());
}
/**
* Gets the names of all persistent properties of this class.
*
* @see #getPersistentProperties()
* @return an unmodifiable collection of property names.
*/
public Collection getPersistentPropertyNames() {
return Collections
.unmodifiableCollection(persistentProperties.keySet());
}
/**
* Gets all the properties of the class. In addition to the persistent
* properties, all public JavaBean properties are also included (even those
* who do not have setter methods).
*
* @return an unmodifiable collection of property metadata.
*/
public Collection getProperties() {
return Collections.unmodifiableCollection(allProperties.values());
}
/**
* Gets the names of all the properties of this class.
*
* @see #getProperties()
* @return an unmodifiable collection of property names.
*/
public Collection getPropertyNames() {
return Collections.unmodifiableCollection(allProperties.keySet());
}
/**
* Gets the metadata of the named property.
*
* @param propertyName
* the name of the property (must not be null).
* @return the property metadata, or null if not found.
*/
public PropertyMetadata getProperty(String propertyName) {
return allProperties.get(propertyName);
}
/**
* Gets the value of property
from object
.
*
* @param object
* the object from which the property will be retrieved (must not
* be null).
* @param property
* the metadata of the property (must not be null).
* @return the property value.
* @throws IllegalArgumentException
* if the property could not be retrieved.
*/
protected Object getPropertyValue(T object, PropertyMetadata property)
throws IllegalArgumentException {
assert object != null : "object must not be null";
assert property != null : "property must not be null";
try {
if (property instanceof PersistentPropertyMetadata) {
PersistentPropertyMetadata ppmd = (PersistentPropertyMetadata) property;
if (ppmd.field != null) {
try {
ppmd.field.setAccessible(true);
return ppmd.field.get(object);
} finally {
ppmd.field.setAccessible(false);
}
}
}
return property.getter.invoke(object);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(
"Cannot access the property value", e);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException(
"Cannot access the property value", e);
}
}
/**
* Sets the value of property
to value
on
* object
.
*
* @param object
* the object to which the property will be set (must not be
* null).
* @param property
* the metadata of the property (must not be null).
* @param value
* the property value.
* @throws IllegalArgumentException
* if the property could not be set.
*/
protected void setPropertyValue(T object, PropertyMetadata property,
Object value) throws IllegalArgumentException {
assert object != null : "object must not be null";
assert property != null : "property must not be null";
if (property != null && property.isWritable()) {
try {
if (property instanceof PersistentPropertyMetadata) {
PersistentPropertyMetadata ppmd = (PersistentPropertyMetadata) property;
if (ppmd.field != null) {
try {
ppmd.field.setAccessible(true);
ppmd.field.set(object, value);
return;
} finally {
ppmd.field.setAccessible(false);
}
}
}
property.setter.invoke(object, value);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(
"Cannot set the property value", e);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException(
"Cannot set the property value", e);
}
} else {
throw new IllegalArgumentException("No such writable property: "
+ property.getName());
}
}
/**
* Gets the getter method for propertyName
from
* parent
.
*
* @param propertyName
* the JavaBean property name (must not be null).
* @param parent
* the class from which to get the getter method (must not be
* null).
* @return the getter method, or null if not found.
*/
protected Method getGetterMethod(String propertyName, Class> parent) {
String methodName = "get" + propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
try {
Method m = parent.getMethod(methodName);
if (m.getReturnType() != Void.TYPE) {
return m;
} else {
return null;
}
} catch (NoSuchMethodException e) {
return null;
}
}
/**
* Gets the setter method for propertyName
from
* parent
.
*
* @param propertyName
* the JavaBean property name (must not be null).
* @param parent
* the class from which to get the setter method (must not be
* null).
* @param propertyType
* the type of the property (must not be null).
* @return the setter method, or null if not found.
*/
protected Method getSetterMethod(String propertyName, Class> parent,
Class> propertyType) {
String methodName = "set" + propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
try {
Method m = parent.getMethod(methodName, propertyType);
if (m.getReturnType() == Void.TYPE) {
return m;
} else {
return null;
}
} catch (NoSuchMethodException e) {
return null;
}
}
/**
* Gets the value of object.propertyName
. The property name may
* be nested.
*
* @param object
* the entity object from which the property value should be
* fetched (must not be null).
* @param propertyName
* the name of the property (must not be null).
* @return the property value.
* @throws IllegalArgumentException
* if the property value could not be fetched, e.g. due to
* propertyName
being invalid.
*/
@SuppressWarnings("unchecked")
public Object getPropertyValue(T object, String propertyName)
throws IllegalArgumentException {
assert object != null : "object must not be null";
assert propertyName != null : "propertyName must not be null";
StringTokenizer st = new StringTokenizer(propertyName, ".");
ClassMetadata
© 2015 - 2025 Weber Informatics LLC | Privacy Policy