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