/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Denise Smith - Initial implementation June 12, 2009 ******************************************************************************/ package org.eclipse.persistence.internal.jaxb.many; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.eclipse.persistence.core.mappings.CoreAttributeAccessor; import org.eclipse.persistence.exceptions.DescriptorException; import org.eclipse.persistence.exceptions.XMLMarshalException; import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy; import org.eclipse.persistence.internal.security.PrivilegedAccessHelper; import org.eclipse.persistence.mappings.AttributeAccessor; /** * AttributeAccessor used in conjunction with an XMLCompositeDirectCollectionMapping * or XMLCompositeCollectionMapping to enable support for mapping to Maps in JAXB */ public class MapValueAttributeAccessor extends AttributeAccessor { private CoreAttributeAccessor nestedAccessor; private String mapClassName; private Class mapClass; private CoreContainerPolicy containerPolicy; private Class generatedEntryClass; private ClassLoader classLoader; public MapValueAttributeAccessor(CoreAttributeAccessor nestedAccessor, CoreContainerPolicy cp, Class generatedEntryClass, String mapClassName, ClassLoader classLoader) { this.nestedAccessor = nestedAccessor; this.mapClassName = mapClassName; this.containerPolicy = cp; this.generatedEntryClass = generatedEntryClass; this.classLoader = classLoader; } public Object getAttributeValueFromObject(Object object)throws DescriptorException { Object value = nestedAccessor.getAttributeValueFromObject(object); if(null == value) { return null; } Object results = containerPolicy.containerInstance(((Map)value).size()); Set<Entry> entrySet = ((Map)value).entrySet(); if(null == entrySet) { return results; } for(Entry entry : entrySet) { MapEntry nextEntry; try { nextEntry = (MapEntry)generatedEntryClass.newInstance(); } catch (Exception e) { return null; } nextEntry.setKey(entry.getKey()); nextEntry.setValue(entry.getValue()); containerPolicy.addInto(nextEntry, results, null); } return results; } public void setAttributeValueInObject(Object object, Object value) throws DescriptorException { Map mapValue = null;; try{ mapValue = (Map)mapClass.newInstance(); } catch (InstantiationException e) { throw XMLMarshalException.unmarshalException(e); } catch (IllegalAccessException e) { throw XMLMarshalException.unmarshalException(e); } if(value != null) { Object iterator = containerPolicy.iteratorFor(value); while(containerPolicy.hasNext(iterator)){ Object next = containerPolicy.next(iterator, null); Object nextKey = ((MapEntry)next).getKey(); Object nextValue = ((MapEntry)next).getValue(); mapValue.put(nextKey, nextValue); } } nestedAccessor.setAttributeValueInObject(object, mapValue); } public void initializeAttributes(Class theJavaClass) throws DescriptorException { nestedAccessor.initializeAttributes(theJavaClass); if(mapClassName.equals("java.util.Map")){ mapClassName = "java.util.HashMap"; } else if(mapClassName.equals("java.util.concurrent.ConcurrentMap")){ mapClassName = "java.util.concurrent.ConcurrentHashMap"; } else if(mapClassName.equals("java.util.SortedMap")){ mapClassName = "java.util.TreeMap"; } try{ mapClass =PrivilegedAccessHelper.getClassForName(mapClassName, true, classLoader); }catch (ClassNotFoundException e){ throw XMLMarshalException.unmarshalException(e); } } }