001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.xml;
014
015import static org.apache.juneau.internal.ClassUtils.*;
016import static org.apache.juneau.internal.StringUtils.*;
017
018import java.util.*;
019
020import org.apache.juneau.*;
021import org.apache.juneau.internal.*;
022import org.apache.juneau.xml.annotation.*;
023
024/**
025 * Metadata on classes specific to the XML serializers and parsers pulled from the {@link Xml @Xml} annotation on the
026 * class.
027 */
028public class XmlClassMeta extends ClassMetaExtended {
029
030   private final Namespace namespace;
031   private final Xml xml;
032   private final XmlFormat format;
033   private final String childName;
034
035   /**
036    * Constructor.
037    *
038    * @param cm The class that this annotation is defined on.
039    */
040   public XmlClassMeta(ClassMeta<?> cm) {
041      super(cm);
042      Class<?> c = getInnerClass();
043      this.namespace = findNamespace(c);
044      this.xml = ClassUtils.getAnnotation(Xml.class, c);
045      if (xml != null) {
046         this.format = xml.format();
047         this.childName = nullIfEmpty(xml.childName());
048
049      } else {
050         this.format = XmlFormat.DEFAULT;
051         this.childName = null;
052      }
053   }
054
055   /**
056    * Returns the {@link Xml @Xml} annotation defined on the class.
057    *
058    * @return
059    *    The value of the annotation defined on the class, or <jk>null</jk> if annotation is not specified.
060    */
061   protected Xml getAnnotation() {
062      return xml;
063   }
064
065   /**
066    * Returns the {@link Xml#format() @Xml(format)} annotation defined on the class.
067    *
068    * @return The value of the annotation, or {@link XmlFormat#DEFAULT} if not specified.
069    */
070   protected XmlFormat getFormat() {
071      return format;
072   }
073
074   /**
075    * Returns the {@link Xml#childName() @Xml(childName)} annotation defined on the class.
076    *
077    * @return The value of the annotation, or <jk>null</jk> if not specified.
078    */
079   protected String getChildName() {
080      return childName;
081   }
082
083   /**
084    * Returns the XML namespace associated with this class.
085    *
086    * <p>
087    * Namespace is determined in the following order of {@link Xml#prefix() @Xml(prefix)} annotation:
088    * <ol>
089    *    <li>Class.
090    *    <li>Package.
091    *    <li>Superclasses.
092    *    <li>Superclass packages.
093    *    <li>Interfaces.
094    *    <li>Interface packages.
095    * </ol>
096    *
097    * @return The namespace associated with this class, or <jk>null</jk> if no namespace is associated with it.
098    */
099   public Namespace getNamespace() {
100      return namespace;
101   }
102
103   private static Namespace findNamespace(Class<?> c) {
104      if (c == null)
105         return null;
106
107      List<Xml> xmls = getAnnotations(Xml.class, c);
108      List<XmlSchema> schemas = getAnnotations(XmlSchema.class, c);
109      return XmlUtils.findNamespace(xmls, schemas);
110   }
111}