001/* 002 * Copyright 2011 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.ametys.plugins.repository.dom; 018 019import java.util.HashMap; 020import java.util.Iterator; 021import java.util.Map; 022 023import org.w3c.dom.Element; 024import org.w3c.dom.Node; 025 026import org.ametys.core.util.dom.AbstractWrappingAmetysElement; 027import org.ametys.core.util.dom.AmetysAttribute; 028import org.ametys.plugins.repository.AmetysObject; 029import org.ametys.plugins.repository.AmetysObjectIterable; 030import org.ametys.plugins.repository.TraversableAmetysObject; 031import org.ametys.plugins.repository.data.ametysobject.ModelLessDataAwareAmetysObject; 032import org.ametys.plugins.repository.metadata.CompositeMetadata; 033import org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType; 034import org.ametys.plugins.repository.metadata.MetadataAwareAmetysObject; 035import org.ametys.runtime.model.type.ElementType; 036import org.ametys.runtime.model.type.ModelItemType; 037 038/** 039 * Implementation of {@link Element} wrapping an {@link AmetysObject}.<br> 040 * Only methods useful for XPath processing are implemented. 041 * @param <A> the actual type of the wrapped {@link AmetysObject}. 042 */ 043public class AmetysObjectElement<A extends AmetysObject> extends AbstractWrappingAmetysElement<A> 044{ 045 /** 046 * Constructor. 047 * @param object the underlying {@link AmetysObject}. 048 */ 049 public AmetysObjectElement(A object) 050 { 051 this(object, null); 052 } 053 054 /** 055 * Constructor. 056 * @param object the underlying {@link AmetysObject}. 057 * @param parent the parent {@link Element}. 058 */ 059 public AmetysObjectElement(A object, AmetysObjectElement<? extends TraversableAmetysObject> parent) 060 { 061 super(object, parent); 062 } 063 064 @Override 065 public String getTagName() 066 { 067 return _object.getName(); 068 } 069 070 /** 071 * This implementation returns all non-composite metadata. 072 */ 073 @Override 074 protected Map<String, AmetysAttribute> _lookupAttributes() 075 { 076 Map<String, AmetysAttribute> result = new HashMap<>(); 077 078 if (_object instanceof ModelLessDataAwareAmetysObject) 079 { 080 ModelLessDataAwareAmetysObject dataHolder = (ModelLessDataAwareAmetysObject) _object; 081 082 for (String name : dataHolder.getDataNames()) 083 { 084 ModelItemType type = dataHolder.getType(name); 085 if (type instanceof ElementType && !dataHolder.isMultiple(name)) 086 { 087 Object value = dataHolder.getValue(name); 088 @SuppressWarnings("unchecked") 089 String valueAsString = ((ElementType) type).toString(value); 090 result.put(name, new AmetysAttribute(name, name, null, valueAsString, this)); 091 } 092 } 093 } 094 else if (_object instanceof MetadataAwareAmetysObject) 095 { 096 CompositeMetadata metadata = ((MetadataAwareAmetysObject) _object).getMetadataHolder(); 097 098 String[] names = metadata.getMetadataNames(); 099 100 for (String name : names) 101 { 102 MetadataType type = metadata.getType(name); 103 if (type != MetadataType.COMPOSITE && type != MetadataType.USER && type != MetadataType.BINARY && type != MetadataType.RICHTEXT && type != MetadataType.OBJECT_COLLECTION && !metadata.isMultiple(name)) 104 { 105 String value = metadata.getString(name); 106 result.put(name, new AmetysAttribute(name, name, null, value, this)); 107 } 108 } 109 } 110 111 return result; 112 } 113 114 @Override 115 public boolean hasChildNodes() 116 { 117 if (_object instanceof TraversableAmetysObject) 118 { 119 AmetysObjectIterable<AmetysObject> children = ((TraversableAmetysObject) _object).getChildren(); 120 121 return children.iterator().hasNext(); 122 } 123 124 return false; 125 } 126 127 @SuppressWarnings("unchecked") 128 @Override 129 public Node getFirstChild() 130 { 131 if (_object instanceof TraversableAmetysObject) 132 { 133 AmetysObjectIterable<AmetysObject> children = ((TraversableAmetysObject) _object).getChildren(); 134 Iterator<AmetysObject> it = children.iterator(); 135 136 if (!it.hasNext()) 137 { 138 return null; 139 } 140 141 return new AmetysObjectElement<>(it.next(), (AmetysObjectElement<TraversableAmetysObject>) this); 142 } 143 144 return null; 145 } 146 147 @SuppressWarnings("unchecked") 148 @Override 149 public Node getNextSibling() 150 { 151 if (_parent == null) 152 { 153 return null; 154 } 155 156 TraversableAmetysObject parent = (TraversableAmetysObject) ((AbstractWrappingAmetysElement) _parent).getWrappedObject(); 157 158 AmetysObjectIterable<AmetysObject> children = parent.getChildren(); 159 160 boolean isNext = false; 161 AmetysObject nextSibling = null; 162 Iterator<AmetysObject> it = children.iterator(); 163 164 while (nextSibling == null && it.hasNext()) 165 { 166 AmetysObject child = it.next(); 167 168 if (isNext) 169 { 170 nextSibling = child; 171 } 172 else if (_object.getId().equals(child.getId())) 173 { 174 isNext = true; 175 } 176 } 177 178 return nextSibling == null ? null : new AmetysObjectElement<>(nextSibling, (AmetysObjectElement< ? extends TraversableAmetysObject>) _parent); 179 } 180}