View Javadoc
1   /*
2    * Copyright 2008 Ange Optimization ApS
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /**
17   * @author Kim Hansen
18   */
19  package eu.simuline.octave.io.spi;
20  
21  import java.io.BufferedReader;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  
26  import java.util.ServiceLoader;
27  
28  import eu.simuline.octave.type.OctaveObject;
29  
30  /**
31   * Service Provider Interface for the IO handler 
32   * that can read {@link OctaveObject}s. 
33   * The octave type which can be read is given by {@link #octaveType()} 
34   * whereas {@link #read(BufferedReader)} performs reading. 
35   * <p>
36   * The according implementations 
37   * are in package {@link eu.simuline.octave.io.impl} 
38   * and extend this class. 
39   * These classes are registered in the jar-file 
40   * under <code>META-INF/services/eu.simuline.octave.io.OctaveDataReader</code>. 
41   */
42  public abstract class OctaveDataReader {
43  
44      /**
45       * Maps the {@link #octaveType()} 
46       * of an {@link OctaveDataReader} to the {@link OctaveDataReader} itself 
47       * which is able to read the octave type from a reader. 
48       */
49      private static Map<String, OctaveDataReader> rEADERS = null;
50  
51      /**
52       * @param type
53       * @return The OctaveDataReader or null if it does not exist
54       */
55      public static OctaveDataReader getOctaveDataReader(final String type) {
56          initReaderIfNecessary();
57          return rEADERS.get(type);
58      }
59  
60      private static synchronized void initReaderIfNecessary() {
61          if (rEADERS != null) {
62              return;
63          }
64  	rEADERS = new HashMap<String, OctaveDataReader>();
65  	final Iterator<OctaveDataReader> sp = 
66  	    ServiceLoader.load(OctaveDataReader.class).iterator();
67  	OctaveDataReader odr, odrOrg;
68  	while (sp.hasNext()) {
69  	    odr = sp.next();
70  	    assert odr != null;
71  	    odrOrg = rEADERS.put(odr.octaveType(), odr);
72  	    if (odrOrg != null) {
73  		 throw new IllegalStateException
74  		     ("Octave type " + odr.octaveType() + 
75  		      " has readers of type " + odr.getClass() + 
76  		      " and " + odrOrg.getClass() + ". ");
77  	    }
78  	}
79      }
80  
81      // TBD: specify more precisely 
82      /**
83       * Could be "scalar" or "string" or something else. 
84       *
85       * @return
86       *    the string representation of the octave type 
87       *    read by this {@link OctaveDataReader} 
88       */
89      public abstract String octaveType();
90  
91      /**
92       * Reads an {@link OctaveObject} from a Reader <code>reader</code>. 
93       * @param reader
94       *    the Reader to read from, will not close reader
95       * @return
96       *   the object read from <code>reader</code>. 
97       */
98      public abstract OctaveObject read(BufferedReader reader);
99  
100 }