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 }