001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.objecttools; 018 019import java.lang.reflect.*; 020import java.util.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.common.utils.*; 024import org.apache.juneau.internal.*; 025 026/** 027 * POJO model viewer. 028 * 029 * <p> 030 * This class is designed to extract properties from collections of maps or beans. 031 * </p> 032 * 033 * <h5 class='section'>Example:</h5> 034 * <p class='bjava'> 035 * MyBean[] <jv>arrayOfBeans</jv> = ...; 036 * ObjectViewer <jv>viewer</jv> = ObjectViewer.<jsm>create</jsm>(); 037 * 038 * <jc>// Returns the 'foo' and 'bar' properties extracted into a list of maps.</jc> 039 * List<Map> <jv>result</jv> = <jv>viewer</jv>.run(<jv>arrayOfBeans</jv>, <js>"foo,bar"</js>); 040 * </p> 041 * <p> 042 * The tool can be used against the following data types: 043 * </p> 044 * <ul> 045 * <li>Arrays/collections of maps or beans. 046 * <li>Singular maps or beans. 047 * </ul> 048 * 049 * <h5 class='section'>See Also:</h5><ul> 050 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ObjectTools">Object Tools</a> 051 052 * </ul> 053 */ 054@SuppressWarnings({"unchecked","rawtypes"}) 055public class ObjectViewer implements ObjectTool<ViewArgs> { 056 057 //----------------------------------------------------------------------------------------------------------------- 058 // Static 059 //----------------------------------------------------------------------------------------------------------------- 060 061 /** 062 * Default reusable searcher. 063 */ 064 public static final ObjectViewer DEFAULT = new ObjectViewer(); 065 066 /** 067 * Static creator. 068 * 069 * @return A new {@link ObjectViewer} object. 070 */ 071 public static ObjectViewer create() { 072 return new ObjectViewer(); 073 } 074 075 //----------------------------------------------------------------------------------------------------------------- 076 // Instance 077 //----------------------------------------------------------------------------------------------------------------- 078 079 /** 080 * Runs this viewer on the specified collection or array of objects. 081 * 082 * @param input The input. Must be an array or collection. 083 * @param args The view args. See {@link ViewArgs} for format. 084 * @return The extracted properties from the collection of objects. 085 */ 086 public List<Map> run(Object input, String args) { 087 return (List<Map>)run(BeanContext.DEFAULT_SESSION, input, ViewArgs.create(args)); 088 } 089 090 /** 091 * Runs this viewer on a singleton object. 092 * 093 * @param input The input. Must be a singleton object. 094 * @param args The view args. See {@link ViewArgs} for format. 095 * @return The extracted properties from the object. 096 */ 097 public Map runSingle(Object input, String args) { 098 return (Map)run(BeanContext.DEFAULT_SESSION, input, ViewArgs.create(args)); 099 } 100 101 @Override /* ObjectTool */ 102 public Object run(BeanSession session, Object input, ViewArgs args) { 103 104 if (input == null) 105 return null; 106 107 List<String> view = args.getView(); 108 ClassMeta type = session.getClassMetaForObject(input); 109 110 if (type.isBeanMap()) 111 return new DelegateBeanMap(((BeanMap)input).getBean(), session).filterKeys(view); 112 if (type.isMap()) 113 return new DelegateMap((Map)input, session).filterKeys(view); 114 if (type.isBean()) 115 return new DelegateBeanMap(input, session).filterKeys(view); 116 117 ArrayList<Object> l = null; 118 119 if (type.isArray()) { 120 int size = Array.getLength(input); 121 l = Utils.listOfSize(size); 122 for (int i = 0; i < size; i++) 123 l.add(Array.get(input, i)); 124 } else if (type.isCollection()) { 125 Collection c = (Collection)input; 126 l = Utils.listOfSize(c.size()); 127 List<Object> l2 = l; 128 c.forEach(x -> l2.add(x)); 129 } else { 130 return input; 131 } 132 133 for (ListIterator li = l.listIterator(); li.hasNext();) { 134 Object o = li.next(); 135 ClassMeta cm2 = session.getClassMetaForObject(o); 136 137 if (cm2 == null) 138 o = null; 139 else if (cm2.isBeanMap()) 140 o = new DelegateBeanMap(((BeanMap)o).getBean(), session).filterKeys(view); 141 else if (cm2.isMap()) 142 o = new DelegateMap((Map)o, session).filterKeys(view); 143 else if (cm2.isBean()) 144 o = new DelegateBeanMap(o, session).filterKeys(view); 145 146 li.set(o); 147 } 148 149 return l; 150 } 151}