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