All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.simpleframework.xml.core.CompositeMap Maven / Gradle / Ivy

Go to download

Simple is a high performance XML serialization and configuration framework for Java

The newest version!
/*
 * CompositeMap.java July 2007
 *
 * Copyright (C) 2007, Niall Gallagher 
 *
 * 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 org.simpleframework.xml.core;

import java.util.Map;

import org.simpleframework.xml.strategy.Type;
import org.simpleframework.xml.stream.InputNode;
import org.simpleframework.xml.stream.OutputNode;
import org.simpleframework.xml.stream.Style;

/**
 * The CompositeMap is used to serialize and deserialize
 * maps to and from a source XML document. The structure of the map in
 * the XML format is determined by the annotation. Keys can be either
 * attributes or elements, and values can be inline. This can perform
 * serialization and deserialization of the key and value objects 
 * whether the object types are primitive or composite.
 * 
 * 
 *    <map>
 *       <entry key='1'>           
 *          <value>one</value>
 *       </entry>
 *       <entry key='2'>
 *          <value>two</value>
 *       </entry>      
 *    </map>
 *    
 * 
* For the above XML element map the element entry is * used to wrap the key and value such that they can be grouped. This * element does not represent any real object. The names of each of * the XML elements serialized and deserialized can be configured. * * @author Niall Gallagher * * @see org.simpleframework.xml.core.Entry */ class CompositeMap implements Converter { /** * The factory used to create suitable map object instances. */ private final MapFactory factory; /** * This is the type that the value objects are instances of. */ private final Converter value; /** * This is the name of the entry wrapping the key and value. */ private final Converter key; /** * This is the style used to style the names used for the XML. */ private final Style style; /** * The entry object contains the details on how to write the map. */ private final Entry entry; /** * Constructor for the CompositeMap object. This will * create a converter that is capable of writing map objects to * and from XML. The resulting XML is configured by an annotation * such that key values can attributes and values can be inline. * * @param context this is the root context for the serialization * @param entry this provides configuration for the resulting XML * @param type this is the map type that is to be converted */ public CompositeMap(Context context, Entry entry, Type type) throws Exception { this.factory = new MapFactory(context, type); this.value = entry.getValue(context); this.key = entry.getKey(context); this.style = context.getStyle(); this.entry = entry; } /** * This read method will read the XML element map from * the provided node and deserialize its children as entry types. * Each entry type must contain a key and value so that the entry * can be inserted in to the map as a pair. If either the key or * value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be deserialized * * @return this returns the item to attach to the object contact */ public Object read(InputNode node) throws Exception{ Instance type = factory.getInstance(node); Object map = type.getInstance(); if(!type.isReference()) { return populate(node, map); } return map; } /** * This read method will read the XML element map from * the provided node and deserialize its children as entry types. * Each entry type must contain a key and value so that the entry * can be inserted in to the map as a pair. If either the key or * value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be deserialized * @param result this is the map object that is to be populated * * @return this returns the item to attach to the object contact */ public Object read(InputNode node, Object result) throws Exception { Instance type = factory.getInstance(node); if(type.isReference()) { return type.getInstance(); } type.setInstance(result); if(result != null) { return populate(node, result); } return result; } /** * This populate method will read the XML element map * from the provided node and deserialize its children as entry types. * Each entry type must contain a key and value so that the entry * can be inserted in to the map as a pair. If either the key or * value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be deserialized * @param result this is the map object that is to be populated * * @return this returns the item to attach to the object contact */ private Object populate(InputNode node, Object result) throws Exception { Map map = (Map) result; while(true) { InputNode next = node.getNext(); if(next == null) { return map; } Object index = key.read(next); Object item = value.read(next); map.put(index, item); } } /** * This validate method will validate the XML element * map from the provided node and validate its children as entry * types. Each entry type must contain a key and value so that the * entry can be inserted in to the map as a pair. If either the key * or value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be validate * * @return true if the element matches the XML schema class given */ public boolean validate(InputNode node) throws Exception{ Instance value = factory.getInstance(node); if(!value.isReference()) { Object result = value.setInstance(null); Class type = value.getType(); return validate(node, type); } return true; } /** * This validate method will validate the XML element * map from the provided node and validate its children as entry * types. Each entry type must contain a key and value so that the * entry can be inserted in to the map as a pair. If either the key * or value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be validate * @param type this is the type to validate the input node against * * @return true if the element matches the XML schema class given */ private boolean validate(InputNode node, Class type) throws Exception { while(true) { InputNode next = node.getNext(); if(next == null) { return true; } if(!key.validate(next)) { return false; } if(!value.validate(next)) { return false; } } } /** * This write method will write the key value pairs * within the provided map to the specified XML node. This will * write each entry type must contain a key and value so that * the entry can be deserialized in to the map as a pair. If the * key or value object is composite it is read as a root object * so its Root annotation must be present. * * @param node this is the node the map is to be written to * @param source this is the source map that is to be written */ public void write(OutputNode node, Object source) throws Exception { Map map = (Map) source; for(Object index : map.keySet()) { String root = entry.getEntry(); String name = style.getElement(root); OutputNode next = node.getChild(name); Object item = map.get(index); key.write(next, index); value.write(next, item); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy