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 }