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.rest.server.beans;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021import org.apache.juneau.commons.bean.*;
022import org.apache.juneau.marshall.*;
023
024/**
025 * Simple serializable bean description.
026 *
027 * <p>
028 * Given a particular class type, this serializes the class into the fully-qualified class name and the properties
029 * associated with the class.
030 *
031 * <p>
032 * Useful for rendering simple information about a bean during REST OPTIONS requests.
033 *
034 * <h5 class='section'>See Also:</h5><ul>
035 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/UtilityBeans">Utility Beans</a>
036
037 * </ul>
038 */
039@BeanType(properties = "type,properties")
040@SuppressWarnings({
041   "java:S1104" // Public fields required for @Marshalled serialization
042})
043public class BeanDescription {
044
045   /**
046    * Information about a bean property.
047    */
048   public static class BeanPropertyDescription {
049
050      /** The bean property name. */
051      public String name;
052
053      /** The bean property filtered class type. */
054      public String type;
055
056      /**
057       * Constructor.
058       *
059       * @param name The bean property name.
060       * @param type The bean property class type.
061       *    <br>Must not be <jk>null</jk>.
062       */
063      public BeanPropertyDescription(String name, ClassMeta<?> type) {
064         this.name = name;
065         this.type = type.getSerializedClassMeta(null).toString();
066      }
067   }
068
069   /**
070    * Static creator.
071    *
072    * @param c The bean being described.
073    *    <br>Must not be <jk>null</jk>.
074    * @return A new bean description.
075    */
076   public static BeanDescription of(Class<?> c) {
077      return new BeanDescription(c);
078   }
079
080   /** The bean class type. */
081   public String type;
082
083   /** The bean properties. */
084   public BeanPropertyDescription[] properties;
085
086   /**
087    * Constructor
088    *
089    * @param c The bean class type.
090    *    <br>Must not be <jk>null</jk>.
091    */
092   public BeanDescription(Class<?> c) {
093      type = c.getName();
094      BeanMeta<?> bm = MarshallingContext.DEFAULT.getBeanMeta(c);
095      if (bm == null)
096         throw rex("Class '%s' is not a valid bean.", cn(c));
097      properties = new BeanPropertyDescription[bm.getProperties().size()];
098      int i = 0;
099      for (var pm : bm.getProperties().values())
100         properties[i++] = new BeanPropertyDescription(pm.getName(), (ClassMeta<?>) pm.getBeanInfo());
101   }
102}