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     * @return
081     */
082    Schema getSchema();
083
084    /**
085     * Gets the super type.
086     *
087     * @return the super type or null if this is a primitive type
088     */
089    Type getSuperType();
090
091    /**
092     * Gets the entire hierarchy of super-types.
093     * <p>
094     * The array is ordered as follows:
095     * <ul>
096     * <li>the direct super type is the first element,
097     * <li>the super super type is the second element,
098     * <li>and so on.
099     * </ul>
100     * <p>
101     * The returned array is never null. An empty array is returned in the case of <code>ANY</code> type.
102     *
103     * @return an array containing the supertypes of this type
104     */
105    Type[] getTypeHierarchy();
106
107    /**
108     * Tests whether the given type is derived from this type.
109     *
110     * @param type the type to test
111     * @return true if the given type is derived from this type, false otherwise
112     */
113    boolean isSuperTypeOf(Type type);
114
115    /**
116     * Tests whether this type is a simple type.
117     *
118     * @return true if this type is a simple type, false otherwise
119     */
120    boolean isSimpleType();
121
122    /**
123     * Tests whether this type is a complex type.
124     *
125     * @return true if this type is a complex type, false otherwise
126     */
127    boolean isComplexType();
128
129    /**
130     * Tests whether this type is a list type.
131     *
132     * @return true if is a list type, false otherwise
133     */
134    boolean isListType();
135
136    /**
137     * Tests whether this type is the ANY type.
138     *
139     * @return true if it is the ANY type, false otherwise
140     */
141    boolean isAnyType();
142
143    /**
144     * Tests whether this is a composite type.
145     *
146     * @return true if this is a composite type, false otherwise
147     */
148    boolean isCompositeType();
149
150    /**
151     * Tests whether the given object is of this type.
152     *
153     * @param object the object to test
154     * @return true if the given object if of this type, false otherwise
155     * @throws TypeException if an error occurs trying to retrieve the supertypes
156     */
157    boolean validate(Object object) throws TypeException;
158
159    // TODO this actually decodes from XSD types. XSD decoding should be moved
160    // to a separate class and not kept inside the Type model.
161    /**
162     * Decodes the string representation into an object of this type.
163     * <p>
164     * Returns null if the string can not be decoded.
165     *
166     * @param string the string to decode
167     * @return the converted object that can be use as a value for an object of this type or null if the given object
168     *         cannot be converted
169     */
170    Object decode(String string);
171
172    /**
173     * Encodes the given object that is assumed to be of this type into a string representation.
174     * <p>
175     * Null is returned if the object cannot be converted.
176     *
177     * @param object the object to convert
178     * @return the string representation of the given object or null if object cannot be converted
179     */
180    String encode(Object object);
181
182    /**
183     * Creates a new instance according to this type and filled with default values.
184     *
185     * @return
186     */
187    Object newInstance();
188
189    /**
190     * Converts the given value to an object compatible with the associated type.
191     *
192     * @param value the value to convert
193     * @return the converted value
194     * @throws TypeException if the value to convert is not compatible with the associated type
195     */
196    Object convert(Object value) throws TypeException;
197
198    /**
199     * @return this type's constraints
200     * @since 7.1
201     */
202    Set<Constraint> getConstraints();
203
204    /**
205     * Provides a {@link ObjectResolver} if this type is a reference to an external entity.
206     *
207     * @return a resolver if available, null otherwise.
208     * @since 7.1
209     */
210    ObjectResolver getObjectResolver();
211
212}