KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > content > MetadataField


1 /*
2  * MetadataField.java
3  *
4  * Version: $Revision: 1.3 $
5  *
6  * Date: $Date: 2006/10/25 11:22:10 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40 package org.dspace.content;
41
42 import java.io.IOException JavaDoc;
43 import java.sql.Connection JavaDoc;
44 import java.sql.PreparedStatement JavaDoc;
45 import java.sql.ResultSet JavaDoc;
46 import java.sql.SQLException JavaDoc;
47 import java.util.ArrayList JavaDoc;
48 import java.util.List JavaDoc;
49 import java.util.HashMap JavaDoc;
50
51 import org.apache.log4j.Logger;
52 import org.dspace.authorize.AuthorizeException;
53 import org.dspace.authorize.AuthorizeManager;
54 import org.dspace.core.Context;
55 import org.dspace.core.LogManager;
56 import org.dspace.storage.rdbms.DatabaseManager;
57 import org.dspace.storage.rdbms.TableRow;
58 import org.dspace.storage.rdbms.TableRowIterator;
59
60 /**
61  * DSpace object that represents a metadata field, which is
62  * defined by a combination of schema, element, and qualifier. Every
63  * metadata element belongs in a field.
64  *
65  * @author Martin Hald
66  * @version $Revision: 1.3 $
67  * @see org.dspace.content.MetadataValue, org.dspace.content.MetadataSchema
68  */

69 public class MetadataField
70 {
71     private int fieldID = 0;
72     private int schemaID = 0;
73     private String JavaDoc element;
74     private String JavaDoc qualifier;
75     private String JavaDoc scopeNote;
76
77     /** log4j logger */
78     private static Logger log = Logger.getLogger(MetadataField.class);
79
80     /** The row in the table representing this type */
81     private TableRow row;
82
83     // cache of field by ID (Integer)
84
private static HashMap JavaDoc id2field = null;
85
86
87     /**
88      * Default constructor.
89      */

90     public MetadataField()
91     {
92     }
93
94     /**
95      * Constructor creating a field within a schema.
96      *
97      * @param schema schema to which the field belongs
98      */

99     public MetadataField(MetadataSchema schema)
100     {
101         this.schemaID = schema.getSchemaID();
102     }
103
104     /**
105      * Full contructor for new metadata field elements.
106      *
107      * @param schema schema to which the field belongs
108      * @param element element of the field
109      * @param qualifier qualifier of the field
110      * @param scopeNote scope note of the field
111      */

112     public MetadataField(MetadataSchema schema, String JavaDoc element,
113             String JavaDoc qualifier, String JavaDoc scopeNote)
114     {
115         this.schemaID = schema.getSchemaID();
116         this.element = element;
117         this.qualifier = qualifier;
118         this.scopeNote = scopeNote;
119     }
120
121     /**
122      * Full construtor for existing metadata field elements.
123      *
124      * @param schemaID schema to which the field belongs
125      * @param fieldID dataabse ID of field.
126      * @param element element of the field
127      * @param qualifier qualifier of the field
128      * @param scopeNote scope note of the field
129      */

130     public MetadataField(int schemaID, int fieldID, String JavaDoc element,
131             String JavaDoc qualifier, String JavaDoc scopeNote)
132     {
133         this.schemaID = schemaID;
134         this.fieldID = fieldID;
135         this.element = element;
136         this.qualifier = qualifier;
137         this.scopeNote = scopeNote;
138     }
139
140     /**
141      * Constructor to load the object from the database.
142      *
143      * @param row database row from which to populate object.
144      */

145     public MetadataField(TableRow row)
146     {
147         if (row != null)
148         {
149             this.fieldID = row.getIntColumn("metadata_field_id");
150             this.schemaID = row.getIntColumn("metadata_schema_id");
151             this.element = row.getStringColumn("element");
152             this.qualifier = row.getStringColumn("qualifier");
153             this.scopeNote = row.getStringColumn("scope_note");
154             this.row = row;
155         }
156     }
157
158     /**
159      * Get the element name.
160      *
161      * @return element name
162      */

163     public String JavaDoc getElement()
164     {
165         return element;
166     }
167
168     /**
169      * Set the element name.
170      *
171      * @param element new value for element
172      */

173     public void setElement(String JavaDoc element)
174     {
175         this.element = element;
176     }
177
178     /**
179      * Get the metadata field id.
180      *
181      * @return metadata field id
182      */

183     public int getFieldID()
184     {
185         return fieldID;
186     }
187
188     /**
189      * Get the qualifier.
190      *
191      * @return qualifier
192      */

193     public String JavaDoc getQualifier()
194     {
195         return qualifier;
196     }
197
198     /**
199      * Set the qualifier.
200      *
201      * @param qualifier new value for qualifier
202      */

203     public void setQualifier(String JavaDoc qualifier)
204     {
205         this.qualifier = qualifier;
206     }
207
208     /**
209      * Get the schema record key.
210      *
211      * @return schema record key
212      */

213     public int getSchemaID()
214     {
215         return schemaID;
216     }
217
218     /**
219      * Set the schema record key.
220      *
221      * @param schemaID new value for key
222      */

223     public void setSchemaID(int schemaID)
224     {
225         this.schemaID = schemaID;
226     }
227
228     /**
229      * Get the scope note.
230      *
231      * @return scope note
232      */

233     public String JavaDoc getScopeNote()
234     {
235         return scopeNote;
236     }
237
238     /**
239      * Set the scope note.
240      *
241      * @param scopeNote new value for scope note
242      */

243     public void setScopeNote(String JavaDoc scopeNote)
244     {
245         this.scopeNote = scopeNote;
246     }
247
248     /**
249      * Creates a new metadata field.
250      *
251      * @param context
252      * DSpace context object
253      * @throws IOException
254      * @throws AuthorizeException
255      * @throws SQLException
256      * @throws NonUniqueMetadataException
257      */

258     public void create(Context context) throws IOException JavaDoc, AuthorizeException,
259             SQLException JavaDoc, NonUniqueMetadataException
260     {
261         // Check authorisation: Only admins may create DC types
262
if (!AuthorizeManager.isAdmin(context))
263         {
264             throw new AuthorizeException(
265                     "Only administrators may modify the metadata registry");
266         }
267
268         // Ensure the element and qualifier are unique within a given schema.
269
if (!unique(context, schemaID, element, qualifier))
270         {
271             throw new NonUniqueMetadataException("Please make " + element + "."
272                     + qualifier + " unique within schema #" + schemaID);
273         }
274
275         // Create a table row and update it with the values
276
row = DatabaseManager.row("MetadataFieldRegistry");
277         row.setColumn("metadata_schema_id", schemaID);
278         row.setColumn("element", element);
279         row.setColumn("qualifier", qualifier);
280         row.setColumn("scope_note", scopeNote);
281         DatabaseManager.insert(context, row);
282         decache();
283
284         // Remember the new row number
285
this.fieldID = row.getIntColumn("metadata_field_id");
286
287         log.info(LogManager.getHeader(context, "create_metadata_field",
288                 "metadata_field_id=" + row.getIntColumn("metadata_field_id")));
289     }
290
291     /**
292      * Retrieves the metadata field from the database.
293      *
294      * @param context dspace context
295      * @param schemaID schema by ID
296      * @param element element name
297      * @param qualifier qualifier (may be ANY or null)
298      * @return recalled metadata field
299      * @throws SQLException
300      * @throws AuthorizeException
301      */

302     public static MetadataField findByElement(Context context, int schemaID,
303             String JavaDoc element, String JavaDoc qualifier) throws SQLException JavaDoc,
304             AuthorizeException
305     {
306         // Grab rows from DB
307
TableRowIterator tri;
308         if (qualifier == null)
309         {
310             tri = DatabaseManager.queryTable(context,"MetadataFieldRegistry",
311                     "SELECT * FROM MetadataFieldRegistry WHERE metadata_schema_id= ? " +
312                     "AND element= ? AND qualifier is NULL ",
313                     schemaID, element);
314         }
315         else
316         {
317             tri = DatabaseManager.queryTable(context,"MetadataFieldRegistry",
318                     "SELECT * FROM MetadataFieldRegistry WHERE metadata_schema_id= ? " +
319                     "AND element= ? AND qualifier= ? ",
320                     schemaID, element, qualifier);
321         }
322         
323
324         TableRow row = null;
325         if (tri.hasNext())
326         {
327             row = tri.next();
328         }
329
330         // close the TableRowIterator to free up resources
331
tri.close();
332
333         if (row == null)
334         {
335             return null;
336         }
337         else
338         {
339             return new MetadataField(row);
340         }
341     }
342
343     /**
344      * Retrieve all Dublin Core types from the registry
345      *
346      * @param context dspace context
347      * @return an array of all the Dublin Core types
348      * @throws SQLException
349      */

350     public static MetadataField[] findAll(Context context) throws SQLException JavaDoc
351     {
352         List JavaDoc fields = new ArrayList JavaDoc();
353
354         // Get all the metadatafieldregistry rows
355
TableRowIterator tri = DatabaseManager.queryTable(context, "MetadataFieldRegistry",
356                                "SELECT mfr.* FROM MetadataFieldRegistry mfr, MetadataSchemaRegistry msr where mfr.metadata_schema_id= msr.metadata_schema_id ORDER BY msr.short_id, mfr.element, mfr.qualifier");
357  
358         // Make into DC Type objects
359
while (tri.hasNext())
360         {
361             fields.add(new MetadataField(tri.next()));
362         }
363         // close the TableRowIterator to free up resources
364
tri.close();
365
366         // Convert list into an array
367
MetadataField[] typeArray = new MetadataField[fields.size()];
368         return (MetadataField[]) fields.toArray(typeArray);
369     }
370
371     /**
372      * Return all metadata fields that are found in a given schema.
373      *
374      * @param context dspace context
375      * @param schemaID schema by db ID
376      * @return array of metadata fields
377      * @throws SQLException
378      */

379     public static MetadataField[] findAllInSchema(Context context, int schemaID)
380             throws SQLException JavaDoc
381     {
382         List JavaDoc fields = new ArrayList JavaDoc();
383
384         // Get all the metadatafieldregistry rows
385
TableRowIterator tri = DatabaseManager.queryTable(context,"MetadataFieldRegistry",
386                 "SELECT * FROM MetadataFieldRegistry WHERE metadata_schema_id= ? " +
387                 " ORDER BY element, qualifier", schemaID);
388
389         // Make into DC Type objects
390
while (tri.hasNext())
391         {
392             fields.add(new MetadataField(tri.next()));
393         }
394         // close the TableRowIterator to free up resources
395
tri.close();
396
397         // Convert list into an array
398
MetadataField[] typeArray = new MetadataField[fields.size()];
399         return (MetadataField[]) fields.toArray(typeArray);
400     }
401
402     /**
403      * Update the metadata field in the database.
404      *
405      * @param context dspace context
406      * @throws SQLException
407      * @throws AuthorizeException
408      * @throws NonUniqueMetadataException
409      * @throws IOException
410      */

411     public void update(Context context) throws SQLException JavaDoc,
412             AuthorizeException, NonUniqueMetadataException, IOException JavaDoc
413     {
414         // Check authorisation: Only admins may update the metadata registry
415
if (!AuthorizeManager.isAdmin(context))
416         {
417             throw new AuthorizeException(
418                     "Only administrators may modiffy the Dublin Core registry");
419         }
420
421         // Check to see if the schema ID was altered. If is was then we will
422
// query to ensure that there is not already a duplicate name field.
423
if (row.getIntColumn("metadata_schema_id") != schemaID)
424         {
425             if (MetadataField.hasElement(context, schemaID, element, qualifier))
426             {
427                 throw new NonUniqueMetadataException(
428                         "Duplcate field name found in target schema");
429             }
430         }
431
432         // Ensure the element and qualifier are unique within a given schema.
433
if (!unique(context, schemaID, element, qualifier))
434         {
435             throw new NonUniqueMetadataException("Please make " + element + "."
436                     + qualifier);
437         }
438
439         row.setColumn("metadata_schema_id", schemaID);
440         row.setColumn("element", element);
441         row.setColumn("qualifier", qualifier);
442         row.setColumn("scope_note", scopeNote);
443         DatabaseManager.update(context, row);
444         decache();
445
446         log.info(LogManager.getHeader(context, "update_metadatafieldregistry",
447                 "metadata_field_id=" + getFieldID() + "element=" + getElement()
448                         + "qualifier=" + getQualifier()));
449     }
450
451     /**
452      * Return true if and only if the schema has a field with the given element
453      * and qualifier pair.
454      *
455      * @param context dspace context
456      * @param schemaID schema by ID
457      * @param element element name
458      * @param qualifier qualifier name
459      * @return true if the field exists
460      * @throws SQLException
461      * @throws AuthorizeException
462      */

463     private static boolean hasElement(Context context, int schemaID,
464             String JavaDoc element, String JavaDoc qualifier) throws SQLException JavaDoc,
465             AuthorizeException
466     {
467         return MetadataField.findByElement(context, schemaID, element,
468                 qualifier) != null;
469     }
470
471     /**
472      * Delete the metadata field.
473      *
474      * @param context dspace context
475      * @throws SQLException
476      * @throws AuthorizeException
477      */

478     public void delete(Context context) throws SQLException JavaDoc, AuthorizeException
479     {
480         // Check authorisation: Only admins may create DC types
481
if (!AuthorizeManager.isAdmin(context))
482         {
483             throw new AuthorizeException(
484                     "Only administrators may modify the metadata registry");
485         }
486
487         log.info(LogManager.getHeader(context, "delete_metadata_field",
488                 "metadata_field_id=" + getFieldID()));
489
490         DatabaseManager.delete(context, row);
491         decache();
492     }
493
494     /**
495      * A sanity check that ensures a given element and qualifier are unique
496      * within a given schema. The check happens in code as we cannot use a
497      * database constraint.
498      *
499      * @param context dspace context
500      * @param schemaID
501      * @param element
502      * @param qualifier
503      * @return true if unique
504      * @throws AuthorizeException
505      * @throws SQLException
506      * @throws IOException
507      */

508     private boolean unique(Context context, int schemaID, String JavaDoc element,
509             String JavaDoc qualifier) throws IOException JavaDoc, SQLException JavaDoc,
510             AuthorizeException
511     {
512         Connection JavaDoc con = context.getDBConnection();
513         TableRow reg = DatabaseManager.row("MetadataFieldRegistry");
514         
515         String JavaDoc query = "SELECT COUNT(*) FROM " + reg.getTable()
516             + " WHERE metadata_schema_id= ? "
517             + " and metadata_field_id != ? "
518             + " and element= ? and qualifier= ? ";
519
520         PreparedStatement JavaDoc statement = con.prepareStatement(query);
521         statement.setInt(1,schemaID);
522         statement.setInt(2,fieldID);
523         statement.setString(3,element);
524         statement.setString(4,qualifier);
525         
526         ResultSet JavaDoc rs = statement.executeQuery();
527
528         int count = 0;
529         if (rs.next())
530         {
531             count = rs.getInt(1);
532         }
533
534         return (count == 0);
535     }
536
537     /**
538      * Return the HTML FORM key for the given field.
539      *
540      * @param schema
541      * @param element
542      * @param qualifier
543      * @return HTML FORM key
544      */

545     public static String JavaDoc formKey(String JavaDoc schema, String JavaDoc element, String JavaDoc qualifier)
546     {
547         if (qualifier == null)
548         {
549             return schema + "_" + element;
550         }
551         else
552         {
553             return schema + "_" + element + "_" + qualifier;
554         }
555     }
556
557     /**
558      * Find the field corresponding to the given numeric ID. The ID is
559      * a database key internal to DSpace.
560      *
561      * @param context
562      * context, in case we need to read it in from DB
563      * @param id
564      * the metadata field ID
565      * @return the metadata field object
566      * @throws SQLException
567      */

568     public static MetadataField find(Context context, int id)
569             throws SQLException JavaDoc
570     {
571         initCache(context);
572
573         // 'sanity check' first.
574
Integer JavaDoc iid = new Integer JavaDoc(id);
575         if (!id2field.containsKey(iid))
576             return null;
577
578         return (MetadataField) id2field.get(iid);
579     }
580
581     // invalidate the cache e.g. after something modifies DB state.
582
private static void decache()
583     {
584         id2field = null;
585     }
586
587     // load caches if necessary
588
private static void initCache(Context context) throws SQLException JavaDoc
589     {
590         if (id2field != null)
591             return;
592         id2field = new HashMap JavaDoc();
593         log.info("Loading MetadataField elements into cache.");
594
595         // Grab rows from DB
596
TableRowIterator tri = DatabaseManager.queryTable(context,"MetadataFieldRegistry",
597                 "SELECT * from MetadataFieldRegistry");
598
599         while (tri.hasNext())
600         {
601             TableRow row = tri.next();
602             int fieldID = row.getIntColumn("metadata_field_id");
603             id2field.put(new Integer JavaDoc(fieldID), new MetadataField(row));
604         }
605
606         // close the TableRowIterator to free up resources
607
tri.close();
608     }
609 }
610
Popular Tags