| /* |
| * Copyright (c) 1998, 2019 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 v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Denise Smith - 2.5.1 - Initial Implementation |
| package org.eclipse.persistence.internal.oxm; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy; |
| import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession; |
| import org.eclipse.persistence.internal.oxm.mappings.VariableXPathCollectionMapping; |
| import org.eclipse.persistence.internal.oxm.record.MarshalRecord; |
| import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext; |
| import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord; |
| import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy; |
| import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType; |
| |
| public class XMLVariableXPathCollectionMappingNodeValue extends XMLVariableXPathMappingNodeValue implements ContainerValue{ |
| |
| VariableXPathCollectionMapping mapping; |
| private int index = -1; |
| |
| |
| public XMLVariableXPathCollectionMappingNodeValue(VariableXPathCollectionMapping variableXPathCollectionMapping) { |
| mapping= variableXPathCollectionMapping; |
| } |
| |
| @Override |
| protected void setOrAddAttributeValue(UnmarshalRecord unmarshalRecord, |
| Object value, XPathFragment xPathFragment, Object collection) { |
| unmarshalRecord.addAttributeValue(this, value); |
| } |
| |
| @Override |
| public VariableXPathCollectionMapping getMapping() { |
| return mapping; |
| } |
| |
| @Override |
| public boolean marshal(XPathFragment xPathFragment, |
| MarshalRecord marshalRecord, Object object, |
| CoreAbstractSession session, NamespaceResolver namespaceResolver) { |
| if (mapping.isReadOnly()) { |
| return false; |
| } |
| CoreContainerPolicy cp = mapping.getContainerPolicy(); |
| Object collection = mapping.getAttributeAccessor().getAttributeValueFromObject(object); |
| if (null == collection) { |
| AbstractNullPolicy wrapperNP = mapping.getWrapperNullPolicy(); |
| if (wrapperNP != null && wrapperNP.getMarshalNullRepresentation().equals(XMLNullRepresentationType.XSI_NIL)) { |
| marshalRecord.nilSimple(namespaceResolver); |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| |
| Object iterator = cp.iteratorFor(collection); |
| if (null != iterator && cp.hasNext(iterator)) { |
| XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver); |
| marshalRecord.closeStartGroupingElements(groupingFragment); |
| } else { |
| return marshalRecord.emptyCollection(xPathFragment, namespaceResolver, mapping.getWrapperNullPolicy() != null); |
| } |
| |
| |
| if(marshalRecord.getMarshaller().isApplicationJSON()){ |
| List<XPathFragment> frags = new ArrayList(); |
| List<List> values = new ArrayList<>(); |
| |
| //sort the elements. Results will be a list of xpathfragments and a corresponding list of |
| //collections associated with those xpathfragments |
| XPathFragment xmlRootFragment; |
| while(cp.hasNext(iterator)) { |
| |
| Object nextValue = cp.next(iterator, session); |
| nextValue = mapping.convertObjectValueToDataValue(nextValue, session, marshalRecord.getMarshaller()); |
| XPathFragment frag = mapping.getXPathFragmentForValue(nextValue, marshalRecord.getNamespaceResolver(), marshalRecord.isNamespaceAware(), marshalRecord.getNamespaceSeparator()); |
| if(frag != null){ |
| |
| int index = frags.indexOf(frag); |
| if(index > -1){ |
| values.get(index).add(nextValue); |
| }else{ |
| frags.add(frag); |
| List valuesList = new ArrayList(); |
| valuesList.add(nextValue); |
| values.add(valuesList); |
| } |
| } |
| |
| } |
| |
| for(int i =0;i < frags.size(); i++){ |
| XPathFragment nextFragment = frags.get(i); |
| List listValue = values.get(i); |
| |
| if(nextFragment != null){ |
| int valueSize = listValue.size(); |
| if(valueSize > 1 ){ |
| marshalRecord.startCollection(); |
| } |
| |
| for(int j=0;j<valueSize; j++){ |
| marshalSingleValue(nextFragment, marshalRecord, object, listValue.get(j), session, namespaceResolver, ObjectMarshalContext.getInstance()); |
| } |
| |
| if(valueSize > 1 ){ |
| marshalRecord.endCollection(); |
| } |
| } |
| } |
| } else{ |
| |
| |
| Object objectValue; |
| while (cp.hasNext(iterator)) { |
| objectValue = cp.next(iterator, session); |
| objectValue = mapping.convertObjectValueToDataValue(objectValue, session, marshalRecord.getMarshaller()); |
| marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, ObjectMarshalContext.getInstance()); |
| } |
| } |
| |
| return true; |
| } |
| |
| @Override |
| public Object getContainerInstance() { |
| return getContainerPolicy().containerInstance(); |
| } |
| |
| @Override |
| public void setContainerInstance(Object object, Object containerInstance) { |
| mapping.setAttributeValueInObject(object, containerInstance); |
| } |
| |
| @Override |
| public CoreContainerPolicy getContainerPolicy() { |
| return mapping.getContainerPolicy(); |
| } |
| |
| @Override |
| public boolean isContainerValue() { |
| return true; |
| } |
| |
| @Override |
| public boolean getReuseContainer() { |
| return mapping.getReuseContainer(); } |
| |
| @Override |
| public int getIndex() { |
| return index; |
| } |
| |
| @Override |
| public boolean isDefaultEmptyContainer() { |
| return mapping.isDefaultEmptyContainer(); |
| } |
| |
| @Override |
| public boolean isWrapperAllowedAsCollectionName() { |
| return false; |
| } |
| |
| @Override |
| public void setIndex(int index) { |
| this.index = index; |
| |
| } |
| |
| @Override |
| public boolean isMixedContentNodeValue() { |
| return true; |
| } |
| |
| } |