View Javadoc

1   /**
2    * Copyright (C) 2005-2009 Alfresco Software Limited.
3    *
4    * This file is part of the Spring Surf Extension project.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.springframework.extensions.webscripts;
20  
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  
27  /**
28   * Maintains a registry of mimetypes (indexed by format and user agent)
29   * 
30   * @author davidc
31   */
32  public class FormatRegistry
33  {
34      // Logger
35      private static final Log logger = LogFactory.getLog(FormatRegistry.class);
36  
37      private Map<String, String> formats;
38      private Map<String, String> mimetypes;
39      private Map<String, Map<String, String>> agentFormats;
40      private Map<String, Map<String, String>> agentMimetypes;
41      private Map<String, FormatReader<Object>> readers;
42      private FormatReader<Object> defaultReader;
43      private Map<String, FormatWriter<Object>> writers;
44  
45  
46      /**
47       * Construct
48       */
49      public FormatRegistry()
50      {
51          formats = new HashMap<String, String>();
52          mimetypes = new HashMap<String, String>();
53          agentFormats = new HashMap<String, Map<String, String>>();
54          agentMimetypes = new HashMap<String, Map<String, String>>();
55          readers = new HashMap<String, FormatReader<Object>>();
56          writers = new HashMap<String, FormatWriter<Object>>();
57      }
58  
59      /**
60       * Set default Reader
61       * 
62       * @param defaultReader
63       */
64      public void setDefaultReader(FormatReader<Object> defaultReader)
65      {
66      	this.defaultReader = defaultReader;
67      }
68      
69      /**
70       * Add a reader
71       * 
72       * @param mimetype
73       * @param reader
74       */
75      public void addReader(FormatReader<Object> reader)
76      {
77          String mimetype = reader.getSourceMimetype();
78          readers.put(reader.getSourceMimetype(), reader);
79          if (logger.isDebugEnabled())
80              logger.debug("Registered format reader: converts mimetype '" + mimetype + "' to class '" + reader.getDestinationClass().getSimpleName() + "'");
81      }
82  
83      /**
84       * Add a writer
85       * 
86       * @param mimetype
87       * @param writer
88       */
89      public void addWriter(FormatWriter<Object> writer)
90      {
91          String mimetype = writer.getDestinationMimetype();
92          Class<? extends Object> clazz = writer.getSourceClass();
93          writers.put(clazz.getName() + "||" + mimetype, writer);
94          if (logger.isDebugEnabled())
95              logger.debug("Registered format writer: converts class '" + clazz.getSimpleName() + "' to mimetype '" + mimetype + "'");
96      }
97      
98      /**
99       * Add formats
100      * 
101      * @param agent
102      * @param formatsToAdd
103      */
104     public void addFormats(String agent, Map<String, String> formatsToAdd)
105     {
106         Map<String, String> formatsForAgent = formats; 
107         if (agent != null)
108         {
109             formatsForAgent = agentFormats.get(agent);
110             if (formatsForAgent == null)
111             {
112                 formatsForAgent = new HashMap<String, String>();
113                 agentFormats.put(agent, formatsForAgent);
114             }
115         }
116         
117         for (Map.Entry<String, String> entry : formatsToAdd.entrySet())
118         {
119             if (logger.isWarnEnabled())
120             {
121                 String val = formatsForAgent.get(entry.getKey());
122                 if (val != null)
123                 {
124                     logger.warn("Replacing mimetype '" + val + "' with '" + entry.getValue() + "' for format '" + entry.getKey() + "' (agent: " + agent + ")");
125                 }
126             }
127             
128             formatsForAgent.put(entry.getKey(), entry.getValue());
129             
130             if (logger.isDebugEnabled())
131                 logger.debug("Registered format '" + entry.getKey() + "' for mimetype '" + entry.getValue() + "' (agent: " + agent + ")");
132         }
133     }
134 
135     /**
136      * Add mimetypes
137      * 
138      * @param agent
139      * @param mimetypesToAdd
140      */
141     public void addMimetypes(String agent, Map<String, String> mimetypesToAdd)
142     {
143         Map<String, String> mimetypesForAgent = mimetypes; 
144         if (agent != null)
145         {
146             mimetypesForAgent = agentMimetypes.get(agent);
147             if (mimetypesForAgent == null)
148             {
149                 mimetypesForAgent = new HashMap<String, String>();
150                 agentMimetypes.put(agent, mimetypesForAgent);
151             }
152         }
153         
154         for (Map.Entry<String, String> entry : mimetypesToAdd.entrySet())
155         {
156             if (logger.isWarnEnabled())
157             {
158                 String val = mimetypesForAgent.get(entry.getKey());
159                 if (val != null)
160                 {
161                     logger.warn("Replacing format '" + val + "' with '" + entry.getValue() + "' for mimetype '" + entry.getKey() + "' (agent: " + agent + ")");
162                 }
163             }
164             
165             mimetypesForAgent.put(entry.getKey(), entry.getValue());
166             
167             if (logger.isDebugEnabled())
168                 logger.debug("Registered mimetype '" + entry.getKey() + "' for format '" + entry.getValue() + "' (agent: " + agent + ")");
169         }
170     }
171 
172     /**
173      * Gets the mimetype for the specified user agent and format
174      * 
175      * @param agent
176      * @param format
177      * @return  mimetype (or null, if one is not registered)
178      */
179     public String getMimeType(String agent, String format)
180     {
181         String mimetype = null;
182         
183         if (agent != null)
184         {
185             Map<String, String> formatsForAgent = agentFormats.get(agent);
186             if (formatsForAgent != null)
187             {
188                 mimetype = formatsForAgent.get(format);
189             }
190         }
191         
192         if (mimetype == null)
193         {
194             mimetype = formats.get(format);
195         }
196 
197         return mimetype;
198     }
199     
200     /**
201      * Gets the format for the specified user agent and mimetype
202      * 
203      * @param agent
204      * @param mimetype
205      * @return  format (or null, if one is not registered)
206      */
207     public String getFormat(String agent, String mimetype)
208     {
209         String format = null;
210         
211         if (agent != null)
212         {
213             Map<String, String> mimetypesForAgent = agentMimetypes.get(agent);
214             if (mimetypesForAgent != null)
215             {
216                 format = mimetypesForAgent.get(mimetype);
217             }
218         }
219         
220         if (format == null)
221         {
222             format = mimetypes.get(mimetype);
223         }
224 
225         return format;
226     }
227 
228     /**
229      * Gets a Format Reader
230      * 
231      * @param mimetype
232      * @return  reader
233      */
234     public FormatReader<Object> getReader(String mimetype)
235     {
236     	if (mimetype == null)
237     	{
238     		return defaultReader;
239     	}
240     	
241         // TODO: lookup by sorted mimetype list (most specific -> least specific)
242     	String generalizedMimetype = mimetype;
243     	while (generalizedMimetype != null)
244     	{
245             FormatReader<Object> reader = readers.get(generalizedMimetype); 
246             if (reader != null)
247             {
248                 return reader;
249             }
250             generalizedMimetype = generalizeMimetype(generalizedMimetype);
251     	}
252     	return null;
253     }
254 
255     /**
256      * Gets a Format Writer
257      * 
258      * @param object
259      * @param mimetype
260      * 
261      * @return  writer
262      */
263     public FormatWriter<Object> getWriter(Object object, String mimetype)
264     {
265         // TODO: lookup by sorted mimetype list (most specific -> least specific)
266         String generalizedMimetype = mimetype; 
267         while (generalizedMimetype != null)
268         {
269             FormatWriter<Object> writer = writers.get(object.getClass().getName() + "||" + generalizedMimetype);
270             if (writer != null)
271             {
272                 return writer;
273             }
274             generalizedMimetype = generalizeMimetype(generalizedMimetype);
275         }
276         return null;
277     }
278 
279     /**
280      * Generalize Mimetype
281      * 
282      * @param mimetype
283      * @return  generalized mimetype (null, if no generalization can be made)
284      */
285     public String generalizeMimetype(String mimetype)
286     {
287         String generalizedMimetype = null;
288         if (mimetype != null)
289         {
290             int params = mimetype.lastIndexOf(";");
291             if (params != -1)
292             {
293                 generalizedMimetype = mimetype.substring(0, params);
294             }
295         }
296         return generalizedMimetype;
297     }
298     
299 }