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.xml;
018
019import static org.apache.juneau.common.utils.Utils.*;
020
021import java.util.*;
022
023import org.apache.juneau.*;
024import org.apache.juneau.xml.annotation.*;
025
026/**
027 * Metadata on classes specific to the XML serializers and parsers pulled from the {@link Xml @Xml} annotation on the
028 * class.
029 *
030 * <h5 class='section'>See Also:</h5><ul>
031 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/XmlBasics">XML Basics</a>
032 * </ul>
033 */
034public class XmlClassMeta extends ExtendedClassMeta {
035
036   private final Namespace namespace;
037   private final XmlFormat format;
038   private final String childName;
039
040   /**
041    * Constructor.
042    *
043    * @param cm The class that this annotation is defined on.
044    * @param mp XML metadata provider (for finding information about other artifacts).
045    */
046   public XmlClassMeta(ClassMeta<?> cm, XmlMetaProvider mp) {
047      super(cm);
048      List<Xml> xmls = list();
049      List<XmlSchema> schemas = list();
050      if (cm != null) {
051         cm.forEachAnnotation(Xml.class, x -> true, x -> xmls.add(x));
052         cm.forEachAnnotation(XmlSchema.class, x -> true, x -> schemas.add(x));
053      }
054      this.namespace = XmlUtils.findNamespace(xmls, schemas);
055
056      String _childName = null;
057      XmlFormat _format = XmlFormat.DEFAULT;
058      for (Xml a : xmls) {
059         if (a.format() != XmlFormat.DEFAULT)
060            _format = a.format();
061         if (! a.childName().isEmpty())
062            _childName = a.childName();
063      }
064      this.format = _format;
065      this.childName = _childName;
066   }
067
068   /**
069    * Returns the {@link Xml#format() @Xml(format)} annotation defined on the class.
070    *
071    * @return The value of the annotation, or {@link XmlFormat#DEFAULT} if not specified.
072    */
073   protected XmlFormat getFormat() {
074      return format;
075   }
076
077   /**
078    * Returns the {@link Xml#childName() @Xml(childName)} annotation defined on the class.
079    *
080    * @return The value of the annotation, or <jk>null</jk> if not specified.
081    */
082   protected String getChildName() {
083      return childName;
084   }
085
086   /**
087    * Returns the XML namespace associated with this class.
088    *
089    * <p>
090    * Namespace is determined in the following order of {@link Xml#prefix() @Xml(prefix)} annotation:
091    * <ol>
092    *    <li>Class.
093    *    <li>Package.
094    *    <li>Superclasses.
095    *    <li>Superclass packages.
096    *    <li>Interfaces.
097    *    <li>Interface packages.
098    * </ol>
099    *
100    * @return The namespace associated with this class, or <jk>null</jk> if no namespace is associated with it.
101    */
102   public Namespace getNamespace() {
103      return namespace;
104   }
105}