001/*
002 * (C) Copyright 2006-2012 Nuxeo SA (http://nuxeo.com/) and others.
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 *
016 * Contributors:
017 *     Bogdan Stefanescu
018 *     Florent Guillaume
019 */
020package org.nuxeo.ecm.core.schema.types;
021
022import java.io.Serializable;
023import java.util.Set;
024
025import org.nuxeo.ecm.core.schema.types.constraints.Constraint;
026import org.nuxeo.ecm.core.schema.types.resolver.ObjectResolver;
027
028/**
029 * A Type object is used to describe some ECM content.
030 * <p>
031 * There are two groups of content types:
032 * <ul>
033 * <li>primitive types - these are builtin types used to describe simple values like string, integers, dates etc
034 * <li>custom types - these are used defined types based on the primitive types
035 * </ul>
036 * Custom types are structured in two groups:
037 * <ul>
038 * <li>simple types - constrained primitive types. Constraints are specific to each primitive type. <br>
039 * For example the "string" type may have constraints like maximum length, regular expression pattern etc. <br>
040 * So you can define a custom simple type as being a string that match the regular expression <code>.+@.+</code>
041 * <li>complex types - structured types that can be expressed as a tree like structure of other primitive, simple or
042 * complex types.
043 * </ul>
044 * The typing system is mainly inspired from XML schemas.
045 * <p>
046 * There is a root type called <code>ANY</code> type. <br>
047 * Apart this special type, each type has a super type (a type from which it is derived)
048 * <p>
049 * On top of this typing system there are two high level content types:
050 * <ul>
051 * <li>schemas - a schema is a complex that can be used to form composite types <br>
052 * Because multiple schemas may live together in a composite type they must provide a namespace to avoid name collisions
053 * inside a composite type
054 * <li>composite types - a composite type is made of several schemas. <br>
055 * You can see a composite type as a type derived from multiple complex super types. <br>
056 * Composite types are used to define ECM documents
057 * </ul>
058 * Type names must not contains a <code>:</code> character. This character may be used internally to prefix the type
059 * name so it must not be used in the type name.
060 */
061public interface Type extends Serializable {
062
063    /**
064     * Gets the name of this type.
065     *
066     * @return the type name
067     */
068    String getName();
069
070    /**
071     * Gets the local name of this type.
072     *
073     * @return the local name
074     */
075    String getSchemaName();
076
077    /**
078     * Gets the schema defining this type.
079     */
080    Schema getSchema();
081
082    /**
083     * Gets the super type.
084     *
085     * @return the super type or null if this is a primitive type
086     */
087    Type getSuperType();
088
089    /**
090     * Gets the entire hierarchy of super-types.
091     * <p>
092     * The array is ordered as follows:
093     * <ul>
094     * <li>the direct super type is the first element,
095     * <li>the super super type is the second element,
096     * <li>and so on.
097     * </ul>
098     * <p>
099     * The returned array is never null. An empty array is returned in the case of <code>ANY</code> type.
100     *
101     * @return an array containing the supertypes of this type
102     */
103    Type[] getTypeHierarchy();
104
105    /**
106     * Tests whether the given type is derived from this type.
107     *
108     * @param type the type to test
109     * @return true if the given type is derived from this type, false otherwise
110     */
111    boolean isSuperTypeOf(Type type);
112
113    /**
114     * Tests whether this type is a simple type.
115     *
116     * @return true if this type is a simple type, false otherwise
117     */
118    boolean isSimpleType();
119
120    /**
121     * Tests whether this type is a complex type.
122     *
123     * @return true if this type is a complex type, false otherwise
124     */
125    boolean isComplexType();
126
127    /**
128     * Tests whether this type is a list type.
129     *
130     * @return true if is a list type, false otherwise
131     */
132    boolean isListType();
133
134    /**
135     * Tests whether this type is the ANY type.
136     *
137     * @return true if it is the ANY type, false otherwise
138     */
139    boolean isAnyType();
140
141    /**
142     * Tests whether this is a composite type.
143     *
144     * @return true if this is a composite type, false otherwise
145     */
146    boolean isCompositeType();
147
148    /**
149     * Tests whether the given object is of this type.
150     *
151     * @param object the object to test
152     * @return true if the given object if of this type, false otherwise
153     * @throws TypeException if an error occurs trying to retrieve the supertypes
154     */
155    boolean validate(Object object) throws TypeException;
156
157    // TODO this actually decodes from XSD types. XSD decoding should be moved
158    // to a separate class and not kept inside the Type model.
159    /**
160     * Decodes the string representation into an object of this type.
161     * <p>
162     * Returns null if the string can not be decoded.
163     *
164     * @param string the string to decode
165     * @return the converted object that can be use as a value for an object of this type or null if the given object
166     *         cannot be converted
167     */
168    Object decode(String string);
169
170    /**
171     * Encodes the given object that is assumed to be of this type into a string representation.
172     * <p>
173     * Null is returned if the object cannot be converted.
174     *
175     * @param object the object to convert
176     * @return the string representation of the given object or null if object cannot be converted
177     */
178    String encode(Object object);
179
180    /**
181     * Creates a new instance according to this type and filled with default values.
182     */
183    Object newInstance();
184
185    /**
186     * Converts the given value to an object compatible with the associated type.
187     *
188     * @param value the value to convert
189     * @return the converted value
190     * @throws TypeException if the value to convert is not compatible with the associated type
191     */
192    Object convert(Object value) throws TypeException;
193
194    /**
195     * @return this type's constraints
196     * @since 7.1
197     */
198    Set<Constraint> getConstraints();
199
200    /**
201     * Provides a {@link ObjectResolver} if this type is a reference to an external entity.
202     *
203     * @return a resolver if available, null otherwise.
204     * @since 7.1
205     */
206    ObjectResolver getObjectResolver();
207
208}