/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.system.server.profileservice.persistence;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jboss.logging.Logger;
import org.jboss.managed.api.ManagedObject;
import org.jboss.metatype.api.types.ArrayMetaType;
import org.jboss.metatype.api.types.CompositeMetaType;
import org.jboss.metatype.api.types.MetaType;
import org.jboss.metatype.api.values.ArrayValue;
import org.jboss.metatype.api.values.CollectionValue;
import org.jboss.metatype.api.values.CompositeValue;
import org.jboss.metatype.api.values.EnumValue;
import org.jboss.metatype.api.values.GenericValue;
import org.jboss.metatype.api.values.MetaValue;
import org.jboss.metatype.api.values.MetaValueFactory;
import org.jboss.metatype.api.values.PropertiesMetaValue;
import org.jboss.metatype.api.values.SimpleValue;
import org.jboss.metatype.api.values.TableValue;
import org.jboss.system.server.profileservice.persistence.xml.NullValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedArrayValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedCollectionValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedCompositeValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedEnumValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedGenericValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedManagedObject;
import org.jboss.system.server.profileservice.persistence.xml.PersistedPair;
import org.jboss.system.server.profileservice.persistence.xml.PersistedPropertiesValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedSimpleValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedTableValue;
import org.jboss.system.server.profileservice.persistence.xml.PersistedValue;
/**
* The AbstractValuePersistence creates a xml representation of MetaValues
* which are used for the ProfileService attachment persistence.
*
* @author <a href="mailto:emuckenh@redhat.com">Emanuel Muckenhuber</a>
* @version $Revision$
*/
public class AbstractValuePersistence
{
/** The logger. */
private static final Logger log = Logger.getLogger(AbstractValuePersistence.class);
/** The meta value factory. */
private final MetaValueFactory metaValueFactory;
/** The plugin. */
private final ManagedObjectPersistencePlugin plugin;
public AbstractValuePersistence(ManagedObjectPersistencePlugin callback, MetaValueFactory metaValueFactory)
{
if(callback == null)
throw new IllegalArgumentException("Null managed object persistence callback.");
if(metaValueFactory == null)
throw new IllegalArgumentException("Null meta value factory.");
this.plugin = callback;
this.metaValueFactory = metaValueFactory;
}
/**
* Get the meta value factory.
*
* @return the meta value factory
*/
public MetaValueFactory getMetaValueFactory()
{
return this.metaValueFactory;
}
protected ManagedObjectPersistencePlugin getPlugin()
{
return this.plugin;
}
/**
* Create the peristed xml meta data.
*
* @param value the meta value
* @param metaType the meta type
* @return the xml value
*/
protected PersistedValue createPersistedValue(MetaValue value, MetaType metaType)
{
return createPersistedValue(value, metaType, null);
}
/**
* Create the peristed xml meta data.
*
* @param value the meta value
* @param metaType the meta type
* @param persisted
* @return the xml value.
*/
protected PersistedValue createPersistedValue(MetaValue value, MetaType metaType, PersistedValue persisted)
{
if(log.isTraceEnabled())
log.trace("creating persisted value for : " + value + " with metaType " + metaType);
if(value == null)
return new NullValue();
// Override the metaType e.g. the MapCompositeValueSupport
metaType = value.getMetaType();
PersistedValue persistedValue = null;
if(metaType.isSimple())
{
persistedValue = createSimpleValue(
(SimpleValue) value);
}
else if(metaType.isEnum())
{
persistedValue = createEnumValue(
(EnumValue) value);
}
else if(metaType.isCollection())
{
persistedValue = createCollectionValue(
(CollectionValue) value);
}
else if(metaType.isGeneric())
{
persistedValue = createGenericValue(
(GenericValue) value);
}
else if(metaType.isComposite())
{
persistedValue = createCompositeValue(
(CompositeValue) value,
(CompositeMetaType) metaType);
}
else if(metaType.isArray())
{
persistedValue = createArrayValue(
(ArrayValue) value,
(ArrayMetaType) metaType);
}
else if(metaType.isTable())
{
persistedValue = createTableValue(
(TableValue) value);
}
else if(metaType.isProperties())
{
persistedValue = createPropertiesValue(
(PropertiesMetaValue) value);
}
else
{
throw new IllegalStateException("unknown metaType");
}
return persistedValue;
}
/**
* Create the persistence enum value.
*
* @param value the enum value
* @return the enum xml meta data
*/
protected PersistedEnumValue createEnumValue(EnumValue value)
{
PersistedEnumValue persistedValue = new PersistedEnumValue();
persistedValue.setValue(value.getValue());
return persistedValue;
}
/**
* Create the persistence simple value.
*
* @param value the simple value
* @return the simple xml meta data
*/
protected PersistedSimpleValue createSimpleValue(SimpleValue value)
{
PersistedSimpleValue persistedValue = new PersistedSimpleValue();
persistedValue.setValue(convertSimple2String(value));
return persistedValue;
}
/**
* Create the persistence collection value.
*
* @param value the collection value
* @return the collection xml meta data
*/
protected PersistedCollectionValue createCollectionValue(CollectionValue value)
{
PersistedCollectionValue collection = new PersistedCollectionValue();
for(MetaValue child : value.getElements())
{
PersistedValue persistedValue = createPersistedValue(child, child.getMetaType());
collection.addValue(persistedValue);
}
return collection;
}
/**
* Create the persistence generic value.
*
* @param value the generic value
* @return the generic xml meta data
*/
protected PersistedGenericValue createGenericValue(GenericValue value)
{
//
PersistedGenericValue generic = new PersistedGenericValue();
return createGenericValue(value, generic);
}
/**
* Create the persistence generic value.
*
* @param value the generic value
* @param the persisted generic value
* @return the generic xml meta data
*/
protected PersistedGenericValue createGenericValue(GenericValue value, PersistedGenericValue generic)
{
Object o = value.getValue();
if(o == null)
return generic;
if(o instanceof ManagedObject)
{
PersistedManagedObject mo;
if(generic.getManagedObject() == null)
mo = plugin.createPersistedManagedObject((ManagedObject) o);
else
mo = plugin.createPersistedManagedObject(generic.getManagedObject(), (ManagedObject) o);
generic.setManagedObject(mo);
}
else
{
throw new IllegalStateException("The value of GenericValue must be a ManagedObject: " + value);
}
return generic;
}
/**
* Create the persistence array value.
*
* @param value the array value
* @return
*/
protected PersistedArrayValue createArrayValue(ArrayValue value, ArrayMetaType metaType)
{
//
PersistedArrayValue array = new PersistedArrayValue();
MetaType elementType = metaType.getElementType();
for (int i = 0; i < value.getLength(); i++)
{
PersistedValue persistedValue = null;
Object subElement = value.getValue(i);
if (subElement instanceof MetaValue)
{
persistedValue = createPersistedValue((MetaValue) subElement, elementType);
}
else if (subElement != null && subElement.getClass().isArray())
{
persistedValue = unwrapArray(array, subElement, elementType);
}
// Add to parent
array.addValue(persistedValue);
}
return array;
}
/**
* Unwrap array.
*
* @param array the parent array
* @param element the array value
* @param type the element meta type
* @return the persistence xml meta data
*/
protected PersistedArrayValue unwrapArray(PersistedArrayValue array, Object element, MetaType type)
{
PersistedArrayValue newElement = new PersistedArrayValue();
int subSize = Array.getLength(element);
for (int i = 0; i < subSize; i++)
{
PersistedValue persistedValue = null;
Object subElement = Array.get(element, i);
if (subElement instanceof MetaValue)
{
persistedValue = createPersistedValue((MetaValue) subElement, type);
}
else if (subElement != null && subElement.getClass().isArray())
{
persistedValue = unwrapArray(newElement, subElement, type);
}
newElement.addValue(persistedValue);
}
return newElement;
}
/**
* Create the persistence composite value.
*
* @param value the composite value
* @param metaType the composite meta type
* @param the persisted composite value
* @return the persistence composite xml meta data
*/
protected PersistedCompositeValue createCompositeValue(CompositeValue value, CompositeMetaType metaType)
{
PersistedCompositeValue composite = new PersistedCompositeValue();
// Fix the values
List<PersistedValue> values = composite.getValues();
if(values == null)
{
values = new ArrayList<PersistedValue>();
composite.setValues(values);
}
for(String item : metaType.itemSet())
{
MetaType itemType = metaType.getType(item);
MetaValue itemValue = value.get(item);
// Create item
PersistedValue persistedValue = createPersistedValue(itemValue, itemType);
persistedValue.setName(item);
values.add(persistedValue);
}
return composite;
}
/**
* Create the persistence table value.
*
* @param value the table value
* @param the persisted table
* @return the persistence table xml meta data
*/
protected PersistedTableValue createTableValue(TableValue value)
{
PersistedTableValue table = new PersistedTableValue();
// Fix the entries
List<PersistedCompositeValue> entries = table.getEntries();
if(entries == null)
{
entries = new ArrayList<PersistedCompositeValue>();
table.setEntries(entries);
}
// Process values
Collection<CompositeValue> values = value.values();
for(CompositeValue entry : values)
{
entries.add(createCompositeValue(entry, entry.getMetaType()));
}
return table;
}
/**
* Create the persistence properties value.
*
* @param value the properties value
* @param the persisted properties
* @return the persistence properties xml meta data
*/
protected PersistedValue createPropertiesValue(PropertiesMetaValue value)
{
PersistedPropertiesValue properties = new PersistedPropertiesValue();
List<PersistedPair> pairs = properties.getEntries();
if(pairs == null)
{
pairs = new ArrayList<PersistedPair>();
properties.setEntries(pairs);
}
for(Object key : value.keySet())
{
Object kvalue = value.get(key);
PersistedPair pair = new PersistedPair(key.toString(), kvalue.toString());
pairs.add(pair);
}
return properties;
}
/**
* Create a emtpy xml meta data, based on the meta type
*
* @param metaType the meta type
* @return the peristence value
*/
protected static PersistedValue emtpyPersistedValue(MetaType metaType)
{
if(metaType.isSimple())
{
return new PersistedSimpleValue();
}
else if(metaType.isEnum())
{
return new PersistedEnumValue();
}
else if(metaType.isCollection())
{
return new PersistedCollectionValue();
}
else if(metaType.isGeneric())
{
return new PersistedGenericValue();
}
else if(metaType.isComposite())
{
return new PersistedCompositeValue();
}
else if(metaType.isTable())
{
return new PersistedTableValue();
}
else if(metaType.isArray())
{
return new PersistedArrayValue();
}
else if(metaType.isProperties())
{
return new PersistedPropertiesValue();
}
else
{
throw new IllegalStateException("unknown metaType");
}
}
/**
* Convert a simple meta value to a String.
*
* @param value the simple meta value.
* @return the string.
*/
protected String convertSimple2String(SimpleValue value)
{
if(value == null)
throw new IllegalArgumentException("Null value.");
Object unwrappedValue = getMetaValueFactory().unwrap(value);
if(unwrappedValue == null)
return null;
// Convert to String
return ("" + unwrappedValue);
}
}