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.runtime.model.type.ElementType; 032import org.ametys.runtime.model.type.ModelItemType; 033 034/** 035 * Implementation of {@link Element} wrapping an {@link AmetysObject}.<br> 036 * Only methods useful for XPath processing are implemented. 037 * @param <A> the actual type of the wrapped {@link AmetysObject}. 038 */ 039public class AmetysObjectElement<A extends AmetysObject> extends AbstractWrappingAmetysElement<A> 040{ 041 /** 042 * Constructor. 043 * @param object the underlying {@link AmetysObject}. 044 */ 045 public AmetysObjectElement(A object) 046 { 047 this(object, null); 048 } 049 050 /** 051 * Constructor. 052 * @param object the underlying {@link AmetysObject}. 053 * @param parent the parent {@link Element}. 054 */ 055 public AmetysObjectElement(A object, AmetysObjectElement<? extends TraversableAmetysObject> parent) 056 { 057 super(object, parent); 058 } 059 060 @Override 061 public String getTagName() 062 { 063 return _object.getName(); 064 } 065 066 /** 067 * This implementation returns all non-composite metadata. 068 */ 069 @Override 070 protected Map<String, AmetysAttribute> _lookupAttributes() 071 { 072 Map<String, AmetysAttribute> result = new HashMap<>(); 073 074 if (_object instanceof AmetysObject ametysObject) 075 { 076 for (String name : ametysObject.getDataNames()) 077 { 078 ModelItemType type = ametysObject.getType(name); 079 if (type instanceof ElementType && !ametysObject.isMultiple(name)) 080 { 081 Object value = ametysObject.getValue(name); 082 @SuppressWarnings("unchecked") 083 String valueAsString = ((ElementType) type).toString(value); 084 result.put(name, new AmetysAttribute(name, name, null, valueAsString, this)); 085 } 086 } 087 } 088 089 return result; 090 } 091 092 @Override 093 public boolean hasChildNodes() 094 { 095 if (_object instanceof TraversableAmetysObject) 096 { 097 AmetysObjectIterable<AmetysObject> children = ((TraversableAmetysObject) _object).getChildren(); 098 099 return children.iterator().hasNext(); 100 } 101 102 return false; 103 } 104 105 @SuppressWarnings("unchecked") 106 @Override 107 public Node getFirstChild() 108 { 109 if (_object instanceof TraversableAmetysObject) 110 { 111 AmetysObjectIterable<AmetysObject> children = ((TraversableAmetysObject) _object).getChildren(); 112 Iterator<AmetysObject> it = children.iterator(); 113 114 if (!it.hasNext()) 115 { 116 return null; 117 } 118 119 return new AmetysObjectElement<>(it.next(), (AmetysObjectElement<TraversableAmetysObject>) this); 120 } 121 122 return null; 123 } 124 125 @SuppressWarnings("unchecked") 126 @Override 127 public Node getNextSibling() 128 { 129 if (_parent == null) 130 { 131 return null; 132 } 133 134 TraversableAmetysObject parent = (TraversableAmetysObject) ((AbstractWrappingAmetysElement) _parent).getWrappedObject(); 135 136 AmetysObjectIterable<AmetysObject> children = parent.getChildren(); 137 138 boolean isNext = false; 139 AmetysObject nextSibling = null; 140 Iterator<AmetysObject> it = children.iterator(); 141 142 while (nextSibling == null && it.hasNext()) 143 { 144 AmetysObject child = it.next(); 145 146 if (isNext) 147 { 148 nextSibling = child; 149 } 150 else if (_object.getId().equals(child.getId())) 151 { 152 isNext = true; 153 } 154 } 155 156 return nextSibling == null ? null : new AmetysObjectElement<>(nextSibling, (AmetysObjectElement< ? extends TraversableAmetysObject>) _parent); 157 } 158}