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