001/*
002 * (C) Copyright 2015 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 *     Nicolas Chapurlat <nchapurlat@nuxeo.com>
018 */
019
020package org.nuxeo.ecm.core.io.registry;
021
022import java.lang.reflect.Type;
023import java.util.Collection;
024
025import javax.ws.rs.core.MediaType;
026
027import org.nuxeo.ecm.core.io.registry.context.RenderingContext;
028import org.nuxeo.ecm.core.io.registry.reflect.Instantiations;
029
030/**
031 * Service to get specialize marshaller.
032 * <p>
033 * This service provides an extension point to register/deregister marshallers.
034 *
035 * <pre>
036 * {@code
037 * <extension target="org.nuxeo.ecm.core.io.MarshallerRegistry" point="marshallers">
038 *   <register class="org.nuxeo.ecm.core.io.marshallers.json.validation.ConstraintWriter" enable="true" />
039 *   <register class="org.nuxeo.ecm.core.io.marshallers.json.validation.DocumentValidationReportWriter" enable="true" />
040 * </extension>
041 * }
042 * </pre>
043 *
044 * </p>
045 * <p>
046 * You can also register/deregister your marshaller programmatically by calling {@link #register(Class)} and
047 * {@link #deregister(Class)}.
048 * </p>
049 * <p>
050 * All marshallers are provided with injected properties.
051 * </p>
052 * <p>
053 * You can get a {@link Writer} using:
054 * <ul>
055 * <li>{@link #getWriter(RenderingContext, Class, MediaType)} A {@link Writer} which manage the given class and mimetype
056 * </li>
057 * <li>{@link #getWriter(RenderingContext, Class, Type, MediaType)} A {@link Writer} which manage the given class and
058 * mimetype, plus the checks the given generic type.</li>
059 * <li>{@link #getAllWriters(RenderingContext, Class, Type, MediaType)} All {@link Writer} which manage the given class
060 * and mimetype, plus the checks the given generic type.</li>
061 * <li>{@link #getInstance(RenderingContext, Class)} An instance of the given {@link Writer} class.</li>
062 * </ul>
063 * </p>
064 * <p>
065 * You can get a {@link Reader} using:
066 * <ul>
067 * <li>{@link #getReader(RenderingContext, Class, MediaType)} A {@link Reader} which manage the given class and mimetype
068 * </li>
069 * <li>{@link #getReader(RenderingContext, Class, Type, MediaType)} A {@link Reader} which manage the given class and
070 * mimetype, plus the checks the given generic type.</li>
071 * <li>{@link #getAllReaders(RenderingContext, Class, Type, MediaType)} All {@link Reader} which manage the given class
072 * and mimetype, plus the checks the given generic type.</li>
073 * <li>{@link #getInstance(RenderingContext, Class)} An instance of the given {@link Reader} class.</li>
074 * </ul>
075 * </p>
076 * <p>
077 * If several marshaller matches a demand of the single instance, the registry use the following rules to choose one:
078 * <ul>
079 * <li>The marshaller with the greatest priority is choosen.</li>
080 * <li>Then, Less instance is better: {@link Instantiations#SINGLETON} are preferred to
081 * {@link Instantiations#PER_THREAD} to {@link Instantiations#EACH_TIME}</li>
082 * <li>Then, Expert is better: A marshaller which manage a subclass is prefered.</li>
083 * <li>Then, references works: A subclass of an existing marshaller is not choosen. You have to specify an higher
084 * priority.</li>
085 * </ul>
086 *
087 * @since 7.2
088 */
089public interface MarshallerRegistry {
090
091    /**
092     * Be careful !!! That's deregister all marshallers.
093     *
094     * @since 7.2
095     */
096    public void clear();
097
098    /**
099     * Makes a marshaller class available.
100     *
101     * @param marshaller The marshaller class.
102     * @throws MarshallingException If marshaller class is null or if it's not a valid marshaller.
103     * @since 7.2
104     */
105    public void register(Class<?> marshaller) throws MarshallingException;
106
107    /**
108     * Remove a marshaller from the registry.
109     *
110     * @param marshaller The marshaller class.
111     * @throws MarshallingException If marshaller class is null or if it's not a valid marshaller.
112     * @since 7.2
113     */
114    public void deregister(Class<?> marshaller) throws MarshallingException;
115
116    /**
117     * Provides a {@link Writer} instance to manage marshalling of the given Java Type and mimetype.
118     *
119     * @param ctx The marshalling context (see {@link RenderingContext}).
120     * @param marshalledClazz The java type to manage.
121     * @param genericType The generic Java type to manage.
122     * @param mediatype The expected mimetype.
123     * @return A valid {@link Writer} instance.
124     * @since 7.2
125     */
126    public <T> Writer<T> getWriter(RenderingContext ctx, Class<T> marshalledClazz, Type genericType, MediaType mediatype);
127
128    /**
129     * Provides a {@link Writer} instance to manage marshalling of the given Java Type and mimetype. It creates a new
130     * instance even for {@link Instantiations#SINGLETON} marshallers.
131     *
132     * @param ctx The marshalling context (see {@link RenderingContext}).
133     * @param marshalledClazz The java type to manage.
134     * @param genericType The generic Java type to manage.
135     * @param mediatype The expected mimetype.
136     * @return A valid {@link Writer} instance.
137     * @since 7.2
138     */
139    public <T> Writer<T> getUniqueWriter(RenderingContext ctx, Class<T> marshalledClazz, Type genericType,
140            MediaType mediatype);
141
142    /**
143     * Provides all {@link Writer} instance that manage marshalling of the given Java Type and mimetype.
144     *
145     * @param ctx The marshalling context (see {@link RenderingContext}).
146     * @param marshalledClazz The java type to manage.
147     * @param genericType The generic Java type to manage.
148     * @param mediatype The expected mimetype.
149     * @return A list of valid {@link Writer} instance.
150     * @since 7.2
151     */
152    public <T> Collection<Writer<T>> getAllWriters(RenderingContext ctx, Class<T> marshalledClazz, Type genericType,
153            MediaType mediatype);
154
155    /**
156     * see {@link #getWriter(RenderingContext, Class, Type, MediaType)}
157     */
158    public <T> Writer<T> getWriter(RenderingContext ctx, Class<T> marshalledClazz, MediaType mediatype);
159
160    /**
161     * Provides a {@link Reader} instance to manage marshalling of a mimetype in a Java Type.
162     *
163     * @param ctx The marshalling context (see {@link RenderingContext}).
164     * @param marshalledClazz The java type to manage.
165     * @param genericType The generic Java type to manage.
166     * @param mediatype The expected mimetype.
167     * @return A valid {@link Reader} instance.
168     * @since 7.2
169     */
170    public <T> Reader<T> getReader(RenderingContext ctx, Class<T> marshalledClazz, Type genericType, MediaType mediatype);
171
172    /**
173     * Provides a {@link Reader} instance to manage marshalling of a mimetype in a Java Type. It creates a new instance
174     * even for {@link Instantiations#SINGLETON} marshallers.
175     *
176     * @param ctx The marshalling context (see {@link RenderingContext}).
177     * @param marshalledClazz The java type to manage.
178     * @param genericType The generic Java type to manage.
179     * @param mediatype The expected mimetype.
180     * @return A valid {@link Reader} instance.
181     * @since 7.2
182     */
183    public <T> Reader<T> getUniqueReader(RenderingContext ctx, Class<T> marshalledClazz, Type genericType,
184            MediaType mediatype);
185
186    /**
187     * Provides all {@link Reader} instance that manage marshalling of a mimetype in a Java Type.
188     *
189     * @param ctx The marshalling context (see {@link RenderingContext}).
190     * @param marshalledClazz The java type to manage.
191     * @param genericType The generic Java type to manage.
192     * @param mediatype The expected mimetype.
193     * @return A list of valid {@link Reader} instance.
194     * @since 7.2
195     */
196    public <T> Collection<Reader<T>> getAllReaders(RenderingContext ctx, Class<T> marshalledClazz, Type genericType,
197            MediaType mediatype);
198
199    /**
200     * see {@link #getReader(RenderingContext, Class, Type, MediaType)}
201     */
202    public <T> Reader<T> getReader(RenderingContext ctx, Class<T> marshalledClazz, MediaType mediatype);
203
204    /**
205     * Provides an instance of a given marshaller class.
206     *
207     * @param ctx The marshalling context (see {@link RenderingContext}).
208     * @param marshallerClass A valid marshaller instance.
209     * @return A valid marshaller instance.
210     * @since 7.2
211     */
212    public <T> T getInstance(RenderingContext ctx, Class<T> marshallerClass);
213
214    /**
215     * Provides an instance of the given marshaller class. It creates a new instance even for
216     * {@link Instantiations#SINGLETON} marshallers.
217     *
218     * @param ctx The marshalling context (see {@link RenderingContext}).
219     * @param marshallerClass A valid marshaller instance.
220     * @return A valid marshaller instance.
221     * @since 7.2
222     */
223    public <T> T getUniqueInstance(RenderingContext ctx, Class<T> marshallerClass);
224
225}