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