Original 2.4
[marc4j.git] / src / org / marc4j / marc / MarcFactory.java
1 //$Id: MarcFactory.java,v 1.2 2006/07/28 16:29:01 bpeters Exp $\r
2 /**\r
3  * Copyright (C) 2004 Bas Peters\r
4  *\r
5  * This file is part of MARC4J\r
6  *\r
7  * MARC4J is free software; you can redistribute it and/or\r
8  * modify it under the terms of the GNU Lesser General Public \r
9  * License as published by the Free Software Foundation; either \r
10  * version 2.1 of the License, or (at your option) any later version.\r
11  *\r
12  * MARC4J is distributed in the hope that it will be useful,\r
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
15  * Lesser General Public License for more details.\r
16  *\r
17  * You should have received a copy of the GNU Lesser General Public \r
18  * License along with MARC4J; if not, write to the Free Software\r
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
20  */\r
21 package org.marc4j.marc;\r
22 \r
23 import java.io.BufferedReader;\r
24 import java.io.File;\r
25 import java.io.FileInputStream;\r
26 import java.io.IOException;\r
27 import java.io.InputStream;\r
28 import java.io.InputStreamReader;\r
29 import java.util.Properties;\r
30 \r
31 /**\r
32  * Factory for creating MARC record objects.\r
33  * <p>\r
34  * You can use <code>MarcFactory</code> to create records from scratch:\r
35  * \r
36  * <pre>\r
37  * \r
38  *  MarcFactory factory = MarcFactory.newInstance();\r
39  *  Record record = factory.newRecord();\r
40  *  ControlField cf = factory.newControlField(&quot;001&quot;);\r
41  *  record.addVariableField(cf);\r
42  *  etc...\r
43  *  \r
44  * </pre>\r
45  * \r
46  * @author Bas Peters\r
47  * @version $Revision: 1.2 $\r
48  */\r
49 public abstract class MarcFactory {\r
50 \r
51   protected MarcFactory() {\r
52   }\r
53 \r
54   /**\r
55    * Creates a new factory instance. The implementation class to load is the\r
56    * first found in the following locations:\r
57    * <ol>\r
58    * <li>the <code>org.marc4j.marc.MarcFactory</code> system property</li>\r
59    * <li>the above named property value in the\r
60    * <code><i>$JAVA_HOME</i>/lib/marc4j.properties</code> file</li>\r
61    * <li>the class name specified in the\r
62    * <code>META-INF/services/org.marc4j.marc.MarcFactory</code> system\r
63    * resource</li>\r
64    * <li>the default factory class</li>\r
65    * </ol>\r
66    */\r
67   public static MarcFactory newInstance() {\r
68     ClassLoader loader = Thread.currentThread().getContextClassLoader();\r
69     if (loader == null) {\r
70       loader = MarcFactory.class.getClassLoader();\r
71     }\r
72     String className = null;\r
73     int count = 0;\r
74     do {\r
75       className = getFactoryClassName(loader, count++);\r
76       if (className != null) {\r
77         try {\r
78           Class t = (loader != null) ? loader.loadClass(className) : Class\r
79               .forName(className);\r
80           return (MarcFactory) t.newInstance();\r
81         } catch (ClassNotFoundException e) {\r
82           className = null;\r
83         } catch (Exception e) {\r
84         }\r
85       }\r
86     } while (className == null && count < 3);\r
87     return new org.marc4j.marc.impl.MarcFactoryImpl();\r
88   }\r
89 \r
90   private static String getFactoryClassName(ClassLoader loader, int attempt) {\r
91     final String propertyName = "org.marc4j.marc.MarcFactory";\r
92     switch (attempt) {\r
93     case 0:\r
94       return System.getProperty(propertyName);\r
95     case 1:\r
96       try {\r
97         File file = new File(System.getProperty("java.home"));\r
98         file = new File(file, "lib");\r
99         file = new File(file, "marc4j.properties");\r
100         InputStream in = new FileInputStream(file);\r
101         Properties props = new Properties();\r
102         props.load(in);\r
103         in.close();\r
104         return props.getProperty(propertyName);\r
105       } catch (IOException e) {\r
106         return null;\r
107       }\r
108     case 2:\r
109       try {\r
110         String serviceKey = "/META-INF/services/" + propertyName;\r
111         InputStream in = (loader != null) ? loader\r
112             .getResourceAsStream(serviceKey) : MarcFactory.class\r
113             .getResourceAsStream(serviceKey);\r
114         if (in != null) {\r
115           BufferedReader r = new BufferedReader(new InputStreamReader(in));\r
116           String ret = r.readLine();\r
117           r.close();\r
118           return ret;\r
119         }\r
120       } catch (IOException e) {\r
121       }\r
122       return null;\r
123     default:\r
124       return null;\r
125     }\r
126   }\r
127 \r
128   /**\r
129    * Returns a new control field instance.\r
130    * \r
131    * @return ControlField\r
132    */\r
133   public abstract ControlField newControlField();\r
134 \r
135   /**\r
136    * Creates a new control field with the given tag and returns the instance.\r
137    * \r
138    * @return ControlField\r
139    */\r
140   public abstract ControlField newControlField(String tag);\r
141 \r
142   /**\r
143    * Creates a new control field with the given tag and data and returns the\r
144    * instance.\r
145    * \r
146    * @return ControlField\r
147    */\r
148   public abstract ControlField newControlField(String tag, String data);\r
149 \r
150   /**\r
151    * Returns a new data field instance.\r
152    * \r
153    * @return DataField\r
154    */\r
155   public abstract DataField newDataField();\r
156 \r
157   /**\r
158    * Creates a new data field with the given tag and indicators and returns the\r
159    * instance.\r
160    * \r
161    * @return DataField\r
162    */\r
163   public abstract DataField newDataField(String tag, char ind1, char ind2);\r
164 \r
165   /**\r
166    * Returns a new leader instance.\r
167    * \r
168    * @return Leader\r
169    */\r
170   public abstract Leader newLeader();\r
171 \r
172   /**\r
173    * Creates a new leader with the given <code>String</code> object.\r
174    * \r
175    * @return Leader\r
176    */\r
177   public abstract Leader newLeader(String ldr);\r
178 \r
179   /**\r
180    * Returns a new record instance.\r
181    * \r
182    * @return Record\r
183    */\r
184   public abstract Record newRecord();\r
185 \r
186   /**\r
187    * Returns a new record instance.\r
188    * \r
189    * @return Record\r
190    */\r
191   public abstract Record newRecord(Leader leader);\r
192     \r
193   /**\r
194    * Returns a new record instance.\r
195    * \r
196    * @return Record\r
197    */\r
198   public abstract Record newRecord(String leader);\r
199   \r
200   /**\r
201    * Returns a new subfield instance.\r
202    * \r
203    * @return Leader\r
204    */\r
205   public abstract Subfield newSubfield();\r
206 \r
207   /**\r
208    * Creates a new subfield with the given identifier.\r
209    * \r
210    * @return Subfield\r
211    */\r
212   public abstract Subfield newSubfield(char code);\r
213 \r
214   /**\r
215    * Creates a new subfield with the given identifier and data.\r
216    * \r
217    * @return Subfield\r
218    */\r
219   public abstract Subfield newSubfield(char code, String data);\r
220 \r
221 }