001 /*
002 * SerialDataStore.java
003 *
004 * Copyright (c) 1995-2010, The University of Sheffield. See the file
005 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006 *
007 * This file is part of GATE (see http://gate.ac.uk/), and is free
008 * software, licenced under the GNU Library General Public License,
009 * Version 2, June 1991 (in the distribution as file licence.html,
010 * and also available at http://gate.ac.uk/gate/licence.html).
011 *
012 * Hamish Cunningham, 19/Jan/2001
013 *
014 * $Id: SerialDataStore.java 12722 2010-06-03 19:53:33Z thomas_heitz $
015 */
016
017 package gate.persist;
018
019 import java.io.*;
020 import java.net.MalformedURLException;
021 import java.net.URISyntaxException;
022 import java.net.URL;
023 import java.util.*;
024 import java.util.zip.GZIPInputStream;
025 import java.util.zip.GZIPOutputStream;
026
027 import gate.*;
028 import gate.corpora.SerialCorpusImpl;
029 import gate.creole.ResourceData;
030 import gate.event.DatastoreEvent;
031 import gate.event.DatastoreListener;
032 import gate.security.*;
033 import gate.security.SecurityException;
034 import gate.util.*;
035
036 /**
037 * A data store based on Java serialisation.
038 */
039 public class SerialDataStore
040 extends AbstractFeatureBearer implements DataStore {
041
042 /** Debug flag */
043 private static final boolean DEBUG = false;
044
045 /** The name of the datastore */
046 protected String name;
047
048 /**
049 * Construction requires a file protocol URL
050 * pointing to the storage directory used for
051 * the serialised classes. <B>NOTE:</B> should not be called except by
052 * GATE code.
053 */
054 public SerialDataStore(String storageDirUrl) throws PersistenceException {
055 setStorageUrl(storageDirUrl);
056 } // construction from URL
057
058 /**
059 * Default construction. <B>NOTE:</B> should not be called except by
060 * GATE code.
061 */
062 public SerialDataStore() { };
063
064 /**
065 * The directory used for the serialised classes.
066 */
067 protected File storageDir;
068
069 /** Set method for storage URL */
070 public void setStorageDir(File storageDir) { this.storageDir = storageDir; }
071
072 /** Get method for storage URL */
073 public File getStorageDir() { return storageDir; }
074
075 /** Set the URL for the underlying storage mechanism. */
076 public void setStorageUrl(String urlString) throws PersistenceException {
077 URL storageUrl = null;
078 try {
079 storageUrl = new URL(urlString);
080 } catch (java.net.MalformedURLException ex) {
081 throw new PersistenceException(
082 "The URL passed is not correct: " + urlString
083 );
084 }
085 if(! storageUrl.getProtocol().equalsIgnoreCase("file"))
086 throw new PersistenceException(
087 "A serial data store needs a file URL, not " + storageUrl
088 );
089 try {
090 this.storageDir = new File(storageUrl.toURI());
091 } catch(URISyntaxException use){
092 this.storageDir = Files.fileFromURL(storageUrl);
093 }
094 } // setStorageUrl
095
096 /** Get the URL for the underlying storage mechanism. */
097 public String getStorageUrl() {
098 if(storageDir == null) return null;
099
100 URL u = null;
101 try { u = storageDir.toURI().toURL(); } catch(MalformedURLException e) {
102 // we can assume that this never happens as storageUrl should always
103 // be a valid file and therefore convertable to URL
104 }
105
106 return u.toString();
107 } // getStorageUrl()
108
109 /** Create a new data store. This tries to create a directory in
110 * the local file system. If the directory already exists and is
111 * non-empty, or is
112 * a file, or cannot be created, PersistenceException is thrown.
113 */
114 public void create()
115 throws PersistenceException {
116 if(storageDir == null)
117 throw new PersistenceException("null storage directory: cannot create");
118
119 if(! storageDir.exists()) { // if doesn't exist create it
120
121 if(! storageDir.mkdir())
122 throw new
123 PersistenceException("cannot create directory " + storageDir);
124 } else { // must be empty
125 String[] existingFiles = filterIgnoredFileNames(storageDir.list());
126 if(! (existingFiles == null || existingFiles.length == 0) )
127 throw new PersistenceException(
128 "directory "+ storageDir +" is not empty: cannot use for data store"
129 );
130 }
131
132 // dump the version file
133 try {
134 File versionFile = getVersionFile();
135 OutputStreamWriter osw = new OutputStreamWriter(
136 new FileOutputStream(versionFile)
137 );
138 osw.write(versionNumber + Strings.getNl());
139 osw.close();
140 } catch(IOException e) {
141 throw new PersistenceException("couldn't write version file: " + e);
142 }
143 } // create()
144
145 /** The name of the version file */
146 protected static String versionFileName = "__GATE_SerialDataStore__";
147
148 /** The protocol version of the currently open data store */
149 protected static String currentProtocolVersion = null;
150
151 /** Get a File for the protocol version file. */
152 protected File getVersionFile() throws IOException {
153 return new File(storageDir, versionFileName);
154 } // getVersionFile
155
156 /**
157 * Version number for variations in the storage protocol.
158 * Protocol versions:
159 * <UL>
160 * <LI>
161 * 1.0: uncompressed. Originally had no version file - to read a 1.0
162 * SerialDataStore that has no version file add a version file containing
163 * the line "1.0".
164 * <LI>
165 * 1.1: has a version file. Uses GZIP compression.
166 * </UL>
167 * This variable stores the version of the current level of the
168 * protocol, NOT the level in use in the currently open data store.
169 */
170 protected String versionNumber = "1.1";
171
172 /** List of valid protocol version numbers. */
173 protected String[] protocolVersionNumbers = {
174 "1.0",
175 "1.1"
176 }; // protocolVersionNumbers
177
178 /** Check a version number for validity. */
179 protected boolean isValidProtocolVersion(String versionNumber) {
180 if(versionNumber == null)
181 return false;
182
183 for(int i = 0; i < protocolVersionNumbers.length; i++)
184 if(protocolVersionNumbers[i].equals(versionNumber))
185 return true;
186
187 return false;
188 } // isValidProtocolVersion
189
190 /** Delete the data store.
191 */
192 public void delete() throws PersistenceException {
193 if(storageDir == null || ! Files.rmdir(storageDir))
194 throw new PersistenceException("couldn't delete " + storageDir);
195
196 Gate.getDataStoreRegister().remove(this);
197 } // delete()
198
199 /** Delete a resource from the data store.
200 */
201 public void delete(String lrClassName, Object lrPersistenceId)
202 throws PersistenceException {
203
204 // find the subdirectory for resources of this type
205 File resourceTypeDirectory = new File(storageDir, lrClassName);
206 if(
207 (! resourceTypeDirectory.exists()) ||
208 (! resourceTypeDirectory.isDirectory())
209 ) {
210 throw new PersistenceException("Can't find " + resourceTypeDirectory);
211 }
212
213 // create a File to representing the resource storage file
214 File resourceFile = new File(resourceTypeDirectory, (String)lrPersistenceId);
215 if(! resourceFile.exists() || ! resourceFile.isFile())
216 throw new PersistenceException("Can't find file " + resourceFile);
217
218 // delete the beast
219 if(! resourceFile.delete())
220 throw new PersistenceException("Can't delete file " + resourceFile);
221
222 // if there are no more resources of this type, delete the dir too
223 if(filterIgnoredFileNames(resourceTypeDirectory.list()).length == 0)
224 if(! resourceTypeDirectory.delete())
225 throw new PersistenceException("Can't delete " + resourceTypeDirectory);
226
227 //let the world know about it
228 fireResourceDeleted(
229 new DatastoreEvent(
230 this, DatastoreEvent.RESOURCE_DELETED, null, (String) lrPersistenceId
231 )
232 );
233 } // delete(lr)
234
235 /** Adopt a resource for persistence. */
236 public LanguageResource adopt(LanguageResource lr,SecurityInfo secInfo)
237 throws PersistenceException,gate.security.SecurityException {
238
239 //ignore security info
240
241 // check the LR's current DS
242 DataStore currentDS = lr.getDataStore();
243 if(currentDS == null) { // an orphan - do the adoption
244 LanguageResource res = lr;
245
246 if (lr instanceof Corpus) {
247 FeatureMap features1 = Factory.newFeatureMap();
248 features1.put("transientSource", lr);
249 try {
250 //here we create the persistent LR via Factory, so it's registered
251 //in GATE
252 res = (LanguageResource)
253 Factory.createResource("gate.corpora.SerialCorpusImpl", features1);
254 //Here the transient corpus is not deleted from the CRI, because
255 //this might not always be the desired behaviour
256 //since we chose that it is for the GUI, this functionality is
257 //now move to the 'Save to' action code in NameBearerHandle
258 } catch (gate.creole.ResourceInstantiationException ex) {
259 throw new GateRuntimeException(ex.getMessage());
260 }
261
262 }
263
264 res.setDataStore(this);
265
266 // let the world know
267 fireResourceAdopted(
268 new DatastoreEvent(this, DatastoreEvent.RESOURCE_ADOPTED, lr, null)
269 );
270 return res;
271 } else if(currentDS.equals(this)) // adopted already here
272 return lr;
273 else { // someone else's child
274 throw new PersistenceException(
275 "Can't adopt a resource which is already in a different datastore"
276 );
277 }
278
279
280 } // adopt(LR)
281
282 /** Open a connection to the data store. */
283 public void open() throws PersistenceException {
284 if(storageDir == null)
285 throw new PersistenceException("Can't open: storage dir is null");
286
287 // check storage directory is readable
288 if(! storageDir.canRead()) {
289 throw new PersistenceException("Can't read " + storageDir);
290 }
291
292 // check storage directory is a valid serial datastore
293 // if we want to support old style:
294 // String versionInVersionFile = "1.0";
295 // (but this means it will open *any* directory)
296 try {
297 FileReader fis = new FileReader(getVersionFile());
298 BufferedReader isr = new BufferedReader(fis);
299 currentProtocolVersion = isr.readLine();
300 if(DEBUG) Out.prln("opening SDS version " + currentProtocolVersion);
301 isr.close();
302 } catch(IOException e) {
303 throw new PersistenceException(
304 "Invalid storage directory: " + e
305 );
306 }
307 if(! isValidProtocolVersion(currentProtocolVersion))
308 throw new PersistenceException(
309 "Invalid protocol version number: " + currentProtocolVersion
310 );
311
312 } // open()
313
314 /** Close the data store. */
315 public void close() throws PersistenceException {
316 Gate.getDataStoreRegister().remove(this);
317 } // close()
318
319 /** Save: synchonise the in-memory image of the LR with the persistent
320 * image.
321 */
322 public void sync(LanguageResource lr) throws PersistenceException {
323 // Out.prln("SDS: LR sync called. Saving " + lr.getClass().getName());
324
325 // check that this LR is one of ours (i.e. has been adopted)
326 if(lr.getDataStore() == null || ! lr.getDataStore().equals(this))
327 throw new PersistenceException(
328 "LR " + lr.getName() + " has not been adopted by this DataStore"
329 );
330
331 // find the resource data for this LR
332 ResourceData lrData =
333 (ResourceData) Gate.getCreoleRegister().get(lr.getClass().getName());
334
335 // create a subdirectory for resources of this type if none exists
336 File resourceTypeDirectory = new File(storageDir, lrData.getClassName());
337 if(
338 (! resourceTypeDirectory.exists()) ||
339 (! resourceTypeDirectory.isDirectory())
340 ) {
341 // try to create the directory, throw an exception if it does not
342 // exist after this attempt. It is possible for mkdir to fail and exists
343 // still to return true if another thread managed to sneak in and
344 // create the directory in the meantime
345 if(! resourceTypeDirectory.mkdir() && ! resourceTypeDirectory.exists())
346 throw new PersistenceException("Can't write " + resourceTypeDirectory);
347 }
348
349 // create an indentifier for this resource
350 String lrName = null;
351 Object lrPersistenceId = null;
352 lrName = lr.getName();
353 lrPersistenceId = lr.getLRPersistenceId();
354
355 if(lrName == null)
356 lrName = lrData.getName();
357 if(lrPersistenceId == null) {
358 lrPersistenceId = constructPersistenceId(lrName);
359 lr.setLRPersistenceId(lrPersistenceId);
360 }
361
362 //we're saving a corpus. I need to save its documents first
363 if (lr instanceof Corpus) {
364 //check if the corpus is the one we support. CorpusImpl cannot be saved!
365 if (! (lr instanceof SerialCorpusImpl))
366 throw new PersistenceException("Can't save a corpus which " +
367 "is not of type SerialCorpusImpl!");
368 SerialCorpusImpl corpus = (SerialCorpusImpl) lr;
369 //this is a list of the indexes of all newly-adopted documents
370 //which will be used by the SerialCorpusImpl to update the
371 //corresponding document IDs
372 for (int i = 0; i < corpus.size(); i++) {
373 //if the document is not in memory, there's little point in saving it
374 if ( (!corpus.isDocumentLoaded(i)) && corpus.isPersistentDocument(i))
375 continue;
376 if (DEBUG)
377 Out.prln("Saving document at position " + i);
378 if (DEBUG)
379 Out.prln("Document in memory " + corpus.isDocumentLoaded(i));
380 if (DEBUG)
381 Out.prln("is persistent? "+ corpus.isPersistentDocument(i));
382 if (DEBUG)
383 Out.prln("Document name at position" + corpus.getDocumentName(i));
384 Document doc = (Document) corpus.get(i);
385 try {
386 //if the document is not already adopted, we need to do that first
387 if (doc.getLRPersistenceId() == null) {
388 if (DEBUG) Out.prln("Document adopted" + doc.getName());
389 doc = (Document) this.adopt(doc, null);
390 this.sync(doc);
391 if (DEBUG) Out.prln("Document sync-ed");
392 corpus.setDocumentPersistentID(i, doc.getLRPersistenceId());
393 } else{
394 //if it is adopted, just sync it
395 this.sync(doc);
396 if (DEBUG) Out.prln("Document sync-ed");
397 }
398 // store the persistent ID. Needs to be done even if the document was
399 //already adopted, in case the doc was already persistent
400 //when added to the corpus
401 corpus.setDocumentPersistentID(i, doc.getLRPersistenceId());
402 if (DEBUG) Out.prln("new document ID " + doc.getLRPersistenceId());
403 } catch (Exception ex) {
404 throw new PersistenceException("Error while saving corpus: "
405 + corpus
406 + "because of an error storing document "
407 + ex.getMessage(), ex);
408 }
409 }//for loop through documents
410 }
411
412 // create a File to store the resource in
413 File resourceFile = new File(resourceTypeDirectory, (String) lrPersistenceId);
414
415 // dump the LR into the new File
416 try {
417 OutputStream os = new FileOutputStream(resourceFile);
418
419 // after 1.1 the serialised files are compressed
420 if(! currentProtocolVersion.equals("1.0"))
421 os = new GZIPOutputStream(os);
422
423 os=new BufferedOutputStream(os);
424
425 ObjectOutputStream oos = new ObjectOutputStream(os);
426 oos.writeObject(lr);
427 oos.close();
428 } catch(IOException e) {
429 throw new PersistenceException("Couldn't write to storage file: " + e);
430 }
431
432 // let the world know about it
433 fireResourceWritten(
434 new DatastoreEvent(
435 this, DatastoreEvent.RESOURCE_WRITTEN, lr, (String) lrPersistenceId
436 )
437 );
438 } // sync(LR)
439
440 /** Create a persistent store Id from the name of a resource. */
441 protected String constructPersistenceId(String lrName) {
442 // change the persistence ID so that it can be used as a filename
443 lrName=lrName.replaceAll("[\\/:\\*\\?\"<>|]","_");
444 return lrName + "___" + new Date().getTime() + "___" + random();
445 } // constructPersistenceId
446
447 /** Get a resource from the persistent store.
448 * <B>Don't use this method - use Factory.createResource with
449 * DataStore and DataStoreInstanceId parameters set instead.</B>
450 * (Sometimes I wish Java had "friend" declarations...)
451 */
452 public LanguageResource getLr(String lrClassName, Object lrPersistenceId)
453 throws PersistenceException,SecurityException {
454
455 // find the subdirectory for resources of this type
456 File resourceTypeDirectory = new File(storageDir, lrClassName);
457 if(
458 (! resourceTypeDirectory.exists()) ||
459 (! resourceTypeDirectory.isDirectory())
460 ) {
461 throw new PersistenceException("Can't find " + resourceTypeDirectory);
462 }
463
464 // create a File to representing the resource storage file
465 File resourceFile = new File(resourceTypeDirectory, (String)lrPersistenceId);
466 if(! resourceFile.exists() || ! resourceFile.isFile())
467 throw new PersistenceException("Can't find file " + resourceFile);
468
469 // try and read the file and deserialise it
470 LanguageResource lr = null;
471 try {
472 InputStream is = new FileInputStream(resourceFile);
473
474 // after 1.1 the serialised files are compressed
475 if(! currentProtocolVersion.equals("1.0"))
476 is = new GZIPInputStream(is);
477
478 is=new BufferedInputStream(is);
479
480 // Use an input stream that is aware of the GATE classloader
481 ObjectInputStream ois = new GateAwareObjectInputStream(is);
482 lr = (LanguageResource) ois.readObject();
483 ois.close();
484 } catch(IOException e) {
485 throw
486 new PersistenceException("Couldn't read file "+resourceFile+": "+e);
487 } catch(ClassNotFoundException ee) {
488 throw
489 new PersistenceException("Couldn't find class "+lrClassName+": "+ee);
490 }
491
492 // set the dataStore property of the LR (which is transient and therefore
493 // not serialised)
494 lr.setDataStore(this);
495 lr.setLRPersistenceId(lrPersistenceId);
496
497 if (DEBUG) Out.prln("LR read in memory: " + lr);
498
499 return lr;
500 } // getLr(id)
501
502 /** Get a list of the types of LR that are present in the data store. */
503 public List getLrTypes() throws PersistenceException {
504 if(storageDir == null || ! storageDir.exists())
505 throw new PersistenceException("Can't read storage directory");
506
507 // filter out the version file
508 String[] fileArray = filterIgnoredFileNames(storageDir.list());
509 List lrTypes = new ArrayList();
510 for(int i=0; i<fileArray.length; i++)
511 if(! fileArray[i].equals(versionFileName))
512 lrTypes.add(fileArray[i]);
513
514 return lrTypes;
515 } // getLrTypes()
516
517 /** Get a list of the IDs of LRs of a particular type that are present. */
518 public List getLrIds(String lrType) throws PersistenceException {
519 // a File to represent the directory for this type
520 File resourceTypeDir = new File(storageDir, lrType);
521 if(! resourceTypeDir.exists())
522 return Arrays.asList(new String[0]);
523
524 return Arrays.asList(filterIgnoredFileNames(resourceTypeDir.list()));
525 } // getLrIds(lrType)
526
527 /** Get a list of the names of LRs of a particular type that are present. */
528 public List getLrNames(String lrType) throws PersistenceException {
529 // the list of files storing LRs of this type; an array for the names
530 String[] lrFileNames = (String[]) getLrIds(lrType).toArray();
531 ArrayList lrNames = new ArrayList();
532
533 // for each lr file name, munge its name and add to the lrNames list
534 for(int i = 0; i<lrFileNames.length; i++) {
535 String name = getLrName(lrFileNames[i]);
536 lrNames.add(name);
537 }
538
539 return lrNames;
540 } // getLrNames(lrType)
541
542 /** Get the name of an LR from its ID. */
543 public String getLrName(Object lrId) {
544 int secondSeparator = ((String) lrId).lastIndexOf("___");
545 lrId = ((String) lrId).substring(0, secondSeparator);
546 int firstSeparator = ((String) lrId).lastIndexOf("___");
547
548 return ((String) lrId).substring(0, firstSeparator);
549 } // getLrName
550
551 /** Set method for the autosaving behaviour of the data store.
552 * <B>NOTE:</B> this type of datastore has no auto-save function,
553 * therefore this method throws an UnsupportedOperationException.
554 */
555 public void setAutoSaving(boolean autoSaving)
556 throws UnsupportedOperationException {
557 throw new UnsupportedOperationException(
558 "SerialDataStore has no auto-save capability"
559 );
560 } // setAutoSaving
561
562 /** Get the autosaving behaviour of the LR. */
563 public boolean isAutoSaving() { return autoSaving; }
564
565 /** Flag for autosaving behaviour. */
566 protected boolean autoSaving = false;
567
568 /** Generate a random integer between 0 and 9999 for file naming. */
569 protected static int random() {
570 return randomiser.nextInt(9999);
571 } // random
572
573 /** Random number generator */
574 protected static Random randomiser = new Random();
575 private transient Vector datastoreListeners;
576
577 /** String representation */
578 public String toString() {
579 String nl = Strings.getNl();
580 StringBuffer s = new StringBuffer("SerialDataStore: ");
581 s.append("autoSaving: " + autoSaving);
582 s.append("; storageDir: " + storageDir);
583 s.append(nl);
584
585 return s.toString();
586 } // toString()
587
588 /** Calculate a hash code based on the class and the storage dir. */
589 public int hashCode(){
590 return getClass().hashCode() ^ storageDir.hashCode();
591 } // hashCode
592
593 /** Equality: based on storage dir of other. */
594 public boolean equals(Object other) {
595
596
597 if (! (other instanceof SerialDataStore))
598 return false;
599
600 if (! ((SerialDataStore)other).storageDir.equals(storageDir))
601 return false;
602
603 //check for the name. First with equals, because they can be both null
604 //in which case trying just with equals leads to a null pointer exception
605 if (((SerialDataStore)other).name == name)
606 return true;
607 else
608 return ((SerialDataStore)other).name.equals(name);
609 } // equals
610
611 public synchronized void removeDatastoreListener(DatastoreListener l) {
612 if (datastoreListeners != null && datastoreListeners.contains(l)) {
613 Vector v = (Vector) datastoreListeners.clone();
614 v.removeElement(l);
615 datastoreListeners = v;
616 }
617 }
618 public synchronized void addDatastoreListener(DatastoreListener l) {
619 Vector v = datastoreListeners == null ? new Vector(2) : (Vector) datastoreListeners.clone();
620 if (!v.contains(l)) {
621 v.addElement(l);
622 datastoreListeners = v;
623 }
624 }
625 protected void fireResourceAdopted(DatastoreEvent e) {
626 if (datastoreListeners != null) {
627 Vector listeners = datastoreListeners;
628 int count = listeners.size();
629 for (int i = 0; i < count; i++) {
630 ((DatastoreListener) listeners.elementAt(i)).resourceAdopted(e);
631 }
632 }
633 }
634 protected void fireResourceDeleted(DatastoreEvent e) {
635 if (datastoreListeners != null) {
636 Vector listeners = datastoreListeners;
637 int count = listeners.size();
638 for (int i = 0; i < count; i++) {
639 ((DatastoreListener) listeners.elementAt(i)).resourceDeleted(e);
640 }
641 }
642 }
643 protected void fireResourceWritten(DatastoreEvent e) {
644 if (datastoreListeners != null) {
645 Vector listeners = datastoreListeners;
646 int count = listeners.size();
647 for (int i = 0; i < count; i++) {
648 ((DatastoreListener) listeners.elementAt(i)).resourceWritten(e);
649 }
650 }
651 }
652
653 /**
654 * Returns the name of the icon to be used when this datastore is displayed
655 * in the GUI
656 */
657 public String getIconName(){
658 return "datastore";
659 }
660
661 /**
662 * Returns the comment displayed by the GUI for this DataStore
663 */
664 public String getComment(){
665 return "GATE serial datastore";
666 }
667
668 /**
669 * Checks if the user (identified by the sessionID)
670 * has read access to the LR
671 */
672 public boolean canReadLR(Object lrID)
673 throws PersistenceException, gate.security.SecurityException{
674
675 return true;
676 }
677 /**
678 * Checks if the user (identified by the sessionID)
679 * has write access to the LR
680 */
681 public boolean canWriteLR(Object lrID)
682 throws PersistenceException, gate.security.SecurityException{
683
684 return true;
685 }
686
687 /** Sets the name of this resource*/
688 public void setName(String name){
689 this.name = name;
690 }
691
692 /** Returns the name of this resource*/
693 public String getName(){
694 return name;
695 }
696
697
698
699 /** get security information for LR . */
700 public SecurityInfo getSecurityInfo(LanguageResource lr)
701 throws PersistenceException {
702
703 throw new UnsupportedOperationException("security information is not supported "+
704 "for DatabaseDataStore");
705 }
706
707 /** set security information for LR . */
708 public void setSecurityInfo(LanguageResource lr,SecurityInfo si)
709 throws PersistenceException, gate.security.SecurityException {
710
711 throw new UnsupportedOperationException("security information is not supported "+
712 "for DatabaseDataStore");
713
714 }
715
716
717 /** identify user using this datastore */
718 public void setSession(Session s)
719 throws gate.security.SecurityException {
720
721 // do nothing
722 }
723
724
725
726 /** identify user using this datastore */
727 public Session getSession(Session s)
728 throws gate.security.SecurityException {
729
730 return null;
731 }
732
733 /**
734 * Try to acquire exlusive lock on a resource from the persistent store.
735 * Always call unlockLR() when the lock is no longer needed
736 */
737 public boolean lockLr(LanguageResource lr)
738 throws PersistenceException,SecurityException {
739 return true;
740 }
741
742 /**
743 * Releases the exlusive lock on a resource from the persistent store.
744 */
745 public void unlockLr(LanguageResource lr)
746 throws PersistenceException,SecurityException {
747 return;
748 }
749
750 /** Get a list of LRs that satisfy some set or restrictions */
751 public List findLrIds(List constraints) throws PersistenceException {
752 throw new UnsupportedOperationException(
753 "Serial DataStore does not support document retrieval.");
754 }
755
756 /**
757 * Get a list of LRs that satisfy some set or restrictions and are
758 * of a particular type
759 */
760 public List findLrIds(List constraints, String lrType) throws PersistenceException {
761 throw new UnsupportedOperationException(
762 "Serial DataStore does not support document retrieval.");
763 }
764
765 /**
766 * This removes the names of all files from a list of file names for which
767 * we know that we want to ignore them.
768 * Currently, all names starting with a dot are ignored.
769 *
770 * @param fileNames
771 * @return the list of file names with the ignored names removed
772 */
773 protected String[] filterIgnoredFileNames(String[] fileNames) {
774 if(fileNames == null || fileNames.length == 0) {
775 return fileNames;
776 }
777 Vector<String> filteredNames = new Vector<String>(fileNames.length);
778 for(String filname : fileNames) {
779 if(!filname.startsWith(".")) {
780 filteredNames.add(filname);
781 }
782 }
783 return filteredNames.toArray(new String[0]);
784 }
785
786
787 } // class SerialDataStore
|