Coverage Report - org.apache.any23.writer.WriterRegistry
 
Classes in this File Line Coverage Branch Coverage Complexity
WriterRegistry
0%
0/56
0%
0/22
2.429
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *  http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 package org.apache.any23.writer;
 19  
 
 20  
 import java.io.OutputStream;
 21  
 import java.util.ArrayList;
 22  
 import java.util.HashMap;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 
 26  
 /**
 27  
  * Registry class for {@link FormatWriter}s.
 28  
  *
 29  
  * @author Michele Mostarda (mostarda@fbk.eu)
 30  
  */
 31  
 public class WriterRegistry {
 32  
 
 33  
     /**
 34  
      * Singleton instance.
 35  
      */
 36  
     private static WriterRegistry instance;
 37  
 
 38  
     /**
 39  
      * List of registered writers.
 40  
      */
 41  0
     private final List<Class<? extends FormatWriter>> writers =
 42  
             new ArrayList<Class<? extends FormatWriter>>();
 43  
 
 44  
     /**
 45  
      * MIME Type to {@link FormatWriter} class.
 46  
      */
 47  0
     private final Map<String,List<Class<? extends FormatWriter>>> mimeToWriter =
 48  
             new HashMap<String, List<Class<? extends FormatWriter>>>();
 49  
 
 50  
     /**
 51  
      * Identifier to {@link FormatWriter} class.
 52  
      */
 53  0
     private final Map<String,Class<? extends FormatWriter>> idToWriter =
 54  
             new HashMap<String, Class<? extends FormatWriter>>();
 55  
 
 56  
     /**
 57  
      * Reads the identifier specified for the given {@link FormatWriter}.
 58  
      *
 59  
      * @param writerClass writer class.
 60  
      * @return identifier.
 61  
      */
 62  
     public static String getIdentifier(Class<? extends FormatWriter> writerClass) {
 63  0
         return getWriterAnnotation(writerClass).identifier();
 64  
     }
 65  
 
 66  
     /**
 67  
      * Reads the <i>MIME Type</i> specified for the given {@link FormatWriter}.
 68  
      *
 69  
      * @param writerClass writer class.
 70  
      * @return MIME type.
 71  
      */
 72  
     public static String getMimeType(Class<? extends FormatWriter> writerClass) {
 73  0
         return getWriterAnnotation(writerClass).mimeType();
 74  
     }
 75  
 
 76  
     /**
 77  
      * @return the {@link WriterRegistry} singleton instance.
 78  
      */
 79  
     public synchronized static WriterRegistry getInstance() {
 80  0
         if(instance == null) {
 81  0
             instance = new WriterRegistry();
 82  
         }
 83  0
         return instance;
 84  
     }
 85  
 
 86  
     /**
 87  
      * Reads the annotation associated to the given {@link FormatWriter}.
 88  
      *
 89  
      * @param writerClass input class.
 90  
      * @return associated annotation.
 91  
      * @throws IllegalArgumentException if the annotation is not declared.
 92  
      */
 93  
     private static Writer getWriterAnnotation(Class<? extends FormatWriter> writerClass) {
 94  0
         final Writer writer = writerClass.getAnnotation(Writer.class);
 95  0
         if(writer == null)
 96  0
             throw new IllegalArgumentException(
 97  
                     String.format("Class %s must be annotated with %s .",writerClass, Writer.class)
 98  
             );
 99  0
         return writer;
 100  
     }
 101  
 
 102  0
     private WriterRegistry() {
 103  0
         register(TurtleWriter.class);
 104  0
         register(RDFXMLWriter.class);
 105  0
         register(NTriplesWriter.class);
 106  0
         register(NQuadsWriter.class);
 107  0
         register(TriXWriter.class);
 108  0
         register(JSONWriter.class);
 109  0
         register(URIListWriter.class);
 110  0
     }
 111  
 
 112  
     /**
 113  
      * Registers a new {@link FormatWriter} to the registry.
 114  
      *
 115  
      * @param writerClass the class of the writer to be registered.
 116  
      * @throws IllegalArgumentException if the id or the mimetype are null
 117  
      *                                  or empty strings or if the identifier has been already defined.
 118  
      */
 119  
     public synchronized void register(Class<? extends FormatWriter> writerClass) {
 120  0
         if(writerClass == null) throw new NullPointerException("writerClass cannot be null.");
 121  0
         final Writer writer = getWriterAnnotation(writerClass);
 122  0
         final String id       = writer.identifier();
 123  0
         final String mimeType = writer.mimeType();
 124  0
         if(id == null || id.trim().length() == 0) {
 125  0
             throw new IllegalArgumentException("Invalid identifier returned by writer " + writer);
 126  
         }
 127  0
         if(mimeType == null || mimeType.trim().length() == 0) {
 128  0
             throw new IllegalArgumentException("Invalid MIME type returned by writer " + writer);
 129  
         }
 130  0
         if(idToWriter.containsKey(id))
 131  0
             throw new IllegalArgumentException("The writer identifier is already declared.");
 132  
 
 133  0
         writers.add(writerClass);
 134  0
         List<Class<? extends FormatWriter>> writerClasses = mimeToWriter.get(mimeType);
 135  0
         if(writerClasses == null) {
 136  0
             writerClasses = new ArrayList<Class<? extends FormatWriter>>();
 137  0
             mimeToWriter.put(mimeType, writerClasses);
 138  
         }
 139  0
         writerClasses.add(writerClass);
 140  0
         idToWriter.put(id, writerClass);
 141  0
     }
 142  
 
 143  
     /**
 144  
      * Verifies if a {@link FormatWriter} with given <code>id</code> identifier has been registered.
 145  
      *
 146  
      * @param id identifier.
 147  
      * @return <code>true</code> if the identifier has been registered, <code>false</code> otherwise.
 148  
      */
 149  
     public synchronized boolean hasIdentifier(String id) {
 150  0
         return idToWriter.containsKey(id);
 151  
     }
 152  
 
 153  
     /**
 154  
      * @return the list of all the specified identifiers.
 155  
      */
 156  
     public synchronized String[] getIdentifiers() {
 157  0
         final String[] ids = new String[writers.size()];
 158  0
         for (int i = 0; i < ids.length; i++) {
 159  0
             ids[i] = getIdentifier( writers.get(i) );
 160  
         }
 161  0
         return ids;
 162  
     }
 163  
 
 164  
     /**
 165  
      * @return the list of MIME types covered by the registered {@link FormatWriter}s.
 166  
      */
 167  
     public synchronized String[] getMimeTypes() {
 168  0
         return mimeToWriter.keySet().toArray( new String[mimeToWriter.keySet().size()] );
 169  
     }
 170  
 
 171  
     /**
 172  
      * @return the list of all the registered {@link FormatWriter}s.
 173  
      */
 174  
     @SuppressWarnings("unchecked")
 175  
     public synchronized Class<? extends FormatWriter>[] getWriters() {
 176  0
         return writers.toArray( new Class[ writers.size() ] );
 177  
     }
 178  
 
 179  
     /**
 180  
      * Returns the {@link FormatWriter} identified by <code>id</code>.
 181  
      *
 182  
      * @param id the writer identifier.
 183  
      * @return the class of the {@link FormatWriter} matching the <code>id</code>
 184  
      *         or <code>null</code> if not found.s
 185  
      */
 186  
     public synchronized Class<? extends FormatWriter> getWriterByIdentifier(String id) {
 187  0
         return idToWriter.get(id);
 188  
     }
 189  
 
 190  
     /**
 191  
      * Returns all the writers matching the specified <code>mimeType</code>.
 192  
      *
 193  
      * @param mimeType a MIMEType.
 194  
      * @return a list of matching writers or an empty list.
 195  
      */
 196  
     @SuppressWarnings("unchecked")
 197  
     public synchronized Class<? extends FormatWriter>[] getWritersByMimeType(String mimeType) {
 198  0
         final List<Class<? extends FormatWriter>> writerClasses = mimeToWriter.get(mimeType);
 199  0
         return writerClasses.toArray( new Class[writerClasses.size()] );
 200  
     }
 201  
 
 202  
     /**
 203  
      * Returns an instance of {@link FormatWriter} ready to write on the given <code>os</code>
 204  
      * {@link OutputStream}.
 205  
      *
 206  
      * @param id the identifier of the {@link FormatWriter} to crate an instance.
 207  
      * @param os the output stream.
 208  
      * @return the not <code>null</code> {@link FormatWriter} instance.
 209  
      * @throws NullPointerException if the <code>id</code> doesn't match any registered writer.
 210  
      */
 211  
     public synchronized FormatWriter getWriterInstanceByIdentifier(String id, OutputStream os) {
 212  0
         final  Class<? extends FormatWriter> writerClazz = getWriterByIdentifier(id);
 213  0
         if(writerClazz == null)
 214  0
             throw new NullPointerException(
 215  
                 String.format("Cannot find writer with id '%s' .", id)
 216  
             );
 217  0
         return createWriter(writerClazz, os);
 218  
     }
 219  
 
 220  
     /**
 221  
      * Crates a writer instance.
 222  
      *
 223  
      * @param clazz class to instantiate.
 224  
      * @param os output stream to pass as constructor argument.
 225  
      * @return created instance.
 226  
      * @throws IllegalArgumentException if an error occurs during instantiation.
 227  
      */
 228  
     private FormatWriter createWriter(Class<? extends FormatWriter> clazz, OutputStream os) {
 229  
         try {
 230  0
             return clazz.getConstructor(OutputStream.class).newInstance(os);
 231  0
         } catch (Exception e) {
 232  0
             throw new IllegalArgumentException("Error while initializing format writer " + clazz + " .");
 233  
         }
 234  
     }
 235  
 
 236  
 }