001/* 002 * Copyright 2020 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 */ 016package org.ametys.runtime.model; 017 018import java.util.Collection; 019 020import org.apache.commons.lang3.StringUtils; 021import org.apache.commons.lang3.Strings; 022 023import org.ametys.runtime.model.exception.UndefinedItemPathException; 024 025/** 026 * Interface for objects that can access to some model items 027 */ 028public interface ModelItemAccessor 029{ 030 /** 031 * Retrieves the child model item with the given name 032 * @param childName name of the model item child to retrieve 033 * @return the child with the given name, or <code>null</code> if no child is found 034 */ 035 public default ModelItem getChild(String childName) 036 { 037 for (ModelItem child : getModelItems()) 038 { 039 if (Strings.CS.equals(child.getName(), childName)) 040 { 041 return child; 042 } 043 044 // If the accessor has no name, check its children 045 if (child.getName() == null && child instanceof ModelItemAccessor) 046 { 047 ModelItem item = ((ModelItemAccessor) child).getChild(childName); 048 if (item != null) 049 { 050 return item; 051 } 052 } 053 } 054 055 return null; 056 } 057 058 /** 059 * Retrieves the model item at given path 060 * @param itemPath the item path 061 * @return the model item. 062 * @throws UndefinedItemPathException if there is no item defined at the given path 063 */ 064 public default ModelItem getModelItem(String itemPath) throws UndefinedItemPathException 065 { 066 String[] pathSegments = StringUtils.split(itemPath, ModelItem.ITEM_PATH_SEPARATOR); 067 068 if (pathSegments.length > 0) 069 { 070 ModelItemAccessor currentAccessor = this; 071 ModelItem child = null; 072 for (int i = 0; i < pathSegments.length; i++) 073 { 074 child = currentAccessor.getChild(pathSegments[i]); 075 076 if (child == null) 077 { 078 throw new UndefinedItemPathException("The item at path '" + itemPath + "' is not defined in the model item accessor '" + toString() + "'."); 079 } 080 else if (i < pathSegments.length - 1 && !(child instanceof ModelItemAccessor)) 081 { 082 String currentAccessorPath = StringUtils.join(pathSegments, ModelItem.ITEM_PATH_SEPARATOR, 0, i + 1); 083 String subItemPath = StringUtils.join(pathSegments, ModelItem.ITEM_PATH_SEPARATOR, i + 1, pathSegments.length); 084 throw new UndefinedItemPathException("In the model item accessor '" + toString() + "', the item at path '" + currentAccessorPath + "' is not a model item accessor. So it can not access to a sub item with path '" + subItemPath + "'."); 085 } 086 else if (child instanceof ModelItemAccessor) 087 { 088 currentAccessor = (ModelItemAccessor) child; 089 } 090 } 091 092 return child; 093 } 094 else 095 { 096 throw new UndefinedItemPathException("The item at path '" + itemPath + "' is not defined in the model item accessor '" + toString() + "'."); 097 } 098 } 099 100 /** 101 * Checks if there is an item defined with the given path 102 * @param itemPath path of the item 103 * @return <code>true</code> if there is an item, <code>false</code> otherwise 104 */ 105 public default boolean hasModelItem(String itemPath) 106 { 107 try 108 { 109 getModelItem(itemPath); 110 return true; 111 } 112 catch (UndefinedItemPathException e) 113 { 114 // The getModelItem method throws an UndefinedItemPathException if there is no model item defined with the given path 115 return false; 116 } 117 } 118 119 /** 120 * Retrieves all the model items of this accessor 121 * @return the model items 122 */ 123 public Collection<? extends ModelItem> getModelItems(); 124}