001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)RegistryImpl.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: /**
030: * RegistryImpl.java
031: *
032: * SUN PROPRIETARY/CONFIDENTIAL.
033: * This software is the proprietary information of Sun Microsystems, Inc.
034: * Use is subject to license terms.
035:
036: * Created on August 22, 2005, 4:27 PM
037: */package com.sun.jbi.management.registry.xml;
038:
039: import com.sun.jbi.ComponentQuery;
040: import com.sun.jbi.platform.PlatformContext;
041: import com.sun.jbi.StringTranslator;
042: import com.sun.jbi.ServiceAssemblyQuery;
043: import com.sun.jbi.management.LocalStringKeys;
044: import com.sun.jbi.management.registry.Registry;
045: import com.sun.jbi.management.registry.RegistrySpec;
046: import com.sun.jbi.management.registry.RegistryException;
047: import com.sun.jbi.management.repository.Repository;
048:
049: import java.io.ByteArrayOutputStream;
050: import java.io.ByteArrayInputStream;
051: import java.io.File;
052: import java.io.FileInputStream;
053: import java.io.FileOutputStream;
054: import java.io.Writer;
055: import java.io.IOException;
056: import java.io.OutputStreamWriter;
057: import java.util.Date;
058: import java.util.Properties;
059: import java.util.logging.Logger;
060: import java.text.DateFormat;
061:
062: import javax.xml.bind.JAXBContext;
063: import javax.xml.bind.JAXBException;
064: import javax.xml.bind.Marshaller;
065: import javax.xml.bind.Unmarshaller;
066: import javax.xml.bind.Validator;
067:
068: import java.util.concurrent.locks.ReentrantReadWriteLock;
069: import java.util.concurrent.TimeUnit;
070: import com.sun.jbi.management.util.LockManager;
071: import com.sun.jbi.management.util.FileHelper;
072: import com.sun.jbi.management.registry.GenericQuery;
073: import com.sun.jbi.management.registry.Updater;
074: import com.sun.jbi.management.system.ManagementContext;
075: import com.sun.jbi.management.system.ManagementException;
076:
077: import org.xml.sax.SAXException;
078:
079: /**
080: * This is an implementation of the Registry which persists the information as XML.
081: *
082: * @author Sun Microsystems, Inc.
083: */
084: public class RegistryImpl implements Registry {
085: /**
086: * The Registry folder and files.
087: */
088: //public static final String REGISTRY_FOLDER_PROPERTY = "jbi.registry.folder";
089: public static final String REGISTRY_FILE = "jbi-registry.xml";
090: public static final String REGISTRY_SYNC_FILE = "jbi-registry-sync.xml";
091: public static final String REGISTRY_BKUP_FILE = "jbi-registry-backup.xml";
092: public static final String REGISTRY_ERROR_FOLDER = "error";
093:
094: /**
095: * registry schema file
096: */
097: public static final String JBI_REGISTRY_SCHEMA = "jbi-registry.xsd";
098:
099: /**
100: * registry schema subdir in JBI_HOME
101: */
102: public static final String JBI_REGISTRY_SCHEMA_DIR = "schemas";
103:
104: /**
105: * The Validation Property : value / { true / false }. Indicates
106: * whether the contents of the registry should be validated before
107: * serialization.
108: */
109: public static final String VALIDATE = "validate";
110:
111: /**
112: * The Registry XML Package.
113: */
114: public static final String REGISTRY_XML_PACKAGE = "com.sun.jbi.management.registry.xml";
115:
116: /**
117: * The Properties for the Registry.
118: */
119: private Properties mProps = null;
120:
121: /**
122: * The Root of the EsbConfiguration.
123: */
124: private Jbi mJbiRegistry;
125:
126: /**
127: * Platform details.
128: */
129: private PlatformContext mPlatform;
130:
131: /**
132: * The Marshaller for persisting the EsbConfiguration.
133: */
134: private Marshaller mMarshaller = null;
135:
136: /**
137: * The LockManager which is used to synchronize access to the
138: * in-memory registry.
139: */
140: private LockManager mRegistryObjRWLockManager;
141:
142: /**
143: * The LockManager which is used to synchronize access to the
144: * serialized registry.
145: */
146: private LockManager mSerializationRWLockManager;
147:
148: /**
149: * The Ctx
150: */
151: private ManagementContext mMgtCtx;
152:
153: private RegistrySpec mSpec;
154:
155: /**
156: *
157: */
158: static final String STRING_TRANSLATOR_NAME = "com.sun.jbi.management";
159:
160: /**
161: *
162: */
163: private StringTranslator mTranslator;
164:
165: /**
166: *
167: */
168: private Logger mLogger;
169:
170: /**
171: * The JAXB Context.
172: */
173: private static JAXBContext sJC;
174:
175: /**
176: * registry path strings
177: */
178: private String mRegistryFolderPath;
179: private String mErrorFolderPath;
180: private String mRegistryFilePath;
181: private String mRegistryFile;
182: private String mRegistrySyncFilePath;
183: private String mRegistrySyncFile;
184: private String mRegistryBackupFilePath;
185:
186: /**
187: * The Registry utility.
188: */
189: private RegistryUtil mRegUtil;
190:
191: /**
192: * registry schema file
193: */
194: private File mRegSchema;
195:
196: /**
197: * @throws RegistryExcepion if the JAXB Context cannot be initialized
198: */
199: private static void initJaxbContext() throws Exception {
200: if (sJC == null) {
201: ClassLoader cl = Class.forName(
202: "com.sun.jbi.management.registry.xml.Jbi")
203: .getClassLoader();
204: sJC = JAXBContext.newInstance(REGISTRY_XML_PACKAGE, cl);
205: }
206: }
207:
208: /**
209: * Creates a new instance of RegistryImpl.
210: *
211: * @param spec - XML Registry specification.
212: * @throws RegistryException if the JAXBContext cannot be initialized.
213: */
214: public RegistryImpl(RegistrySpec spec) throws RegistryException {
215: String regFile;
216: String syncFile;
217:
218: mSpec = spec;
219: mProps = spec.getProperties();
220: mRegistryObjRWLockManager = null;
221: mSerializationRWLockManager = null;
222:
223: mLogger = Logger.getLogger("com.sun.jbi.management.registry");
224:
225: mMgtCtx = spec.getManagementContext();
226: mPlatform = mMgtCtx.getEnvironmentContext()
227: .getPlatformContext();
228: mTranslator = mMgtCtx.getEnvironmentContext()
229: .getStringTranslator(STRING_TRANSLATOR_NAME);
230: mRegistryFolderPath = mProps
231: .getProperty(REGISTRY_FOLDER_PROPERTY);
232: mErrorFolderPath = mRegistryFolderPath + File.separator
233: + REGISTRY_ERROR_FOLDER;
234:
235: //
236: // Allow opening different named file.
237: //
238: if ((regFile = mProps.getProperty(REGISTRY_FILE_PROPERTY)) == null) {
239: regFile = REGISTRY_FILE;
240: }
241:
242: mRegistryFile = regFile;
243: mRegistryFilePath = mRegistryFolderPath + File.separator
244: + regFile;
245: mRegistryBackupFilePath = mRegistryFolderPath + File.separator
246: + REGISTRY_BKUP_FILE;
247:
248: try {
249: File schemaDir = new File(mMgtCtx.getEnvironmentContext()
250: .getJbiInstallRoot(), JBI_REGISTRY_SCHEMA_DIR);
251: mRegSchema = new File(schemaDir, JBI_REGISTRY_SCHEMA);
252:
253: initJaxbContext();
254: } catch (Exception ex) {
255: String errMsg = mTranslator.getString(
256: LocalStringKeys.JBI_ADMIN_FAILED_JAXB_INIT, ex
257: .toString());
258: mLogger.severe(errMsg);
259:
260: throw new RegistryException(errMsg, ex);
261: }
262: mJbiRegistry = initJbiRegistry();
263:
264: try {
265: // -- Make sure registry and repository are in sync
266: mRegUtil = new RegistryUtil(mMgtCtx, this );
267: mRegUtil.syncWithRepository();
268: } catch (Exception ex) {
269: throw new RegistryException(ex);
270: }
271: }
272:
273: /**
274: * Destroy the Registry
275: */
276: public void destroy() {
277: // -- Delete the esb registry files and derefernce memory object
278: File regFile = new File(getRegistryFilePath());
279: File bkupFile = new File(getRegistryBkupFilePath());
280:
281: if (regFile.exists()) {
282: regFile.delete();
283: }
284:
285: if (bkupFile.exists()) {
286: bkupFile.delete();
287: }
288:
289: mJbiRegistry = null;
290: }
291:
292: /**
293: * Initialize the registry
294: */
295: public void reinitialize() throws RegistryException {
296: mJbiRegistry = null;
297: initJbiRegistry();
298: }
299:
300: /**
301: * Get the Esb Configuration Root. If the esb configuration is not loaded, it is
302: * loaded anew.
303: *
304: * @return the EsbConfiguration root.
305: * @throws RegistryException if the in-memory Registry cannot be created
306: */
307: private synchronized Jbi initJbiRegistry() throws RegistryException {
308: if (mJbiRegistry == null) {
309: try {
310: String lockWaitInterval = mProps
311: .getProperty(Registry.REGISTRY_LOCK_INTERVAL_PROPERTY);
312: mRegistryObjRWLockManager = new LockManager(
313: new ReentrantReadWriteLock(),
314: "Registry Object Lock", mMgtCtx,
315: lockWaitInterval);
316: mSerializationRWLockManager = new LockManager(
317: new ReentrantReadWriteLock(),
318: "Registry Serialization Lock", mMgtCtx,
319: lockWaitInterval);
320:
321: mMarshaller = sJC.createMarshaller();
322: mMarshaller.setProperty("jaxb.formatted.output",
323: new Boolean(true));
324:
325: mMarshaller
326: .setSchema(javax.xml.validation.SchemaFactory
327: .newInstance(
328: javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)
329: .newSchema(mRegSchema));
330:
331: File regFile = new File(getRegistryFilePath());
332: File bkupFile = new File(getRegistryBkupFilePath());
333:
334: mLogger.finer("Registry file is "
335: + getRegistryFilePath());
336: /**
337: if ( regFile.exists() && regFile.length() == 0 )
338: {
339: mLogger.info("Deleting ZERO length " + getRegistryFilePath());
340: regFile.delete();
341: }*/
342:
343: if (!regFile.exists())
344:
345: {
346: if (!bkupFile.exists()) {
347: createPrimaryRegistry();
348: } else {
349: loadBackupRegistry();
350: }
351: } else {
352: try {
353: loadPrimaryRegistry();
354: } catch (Exception ex) {
355: mLogger.warning(ex.toString());
356: if (bkupFile.exists()) {
357: loadBackupRegistry();
358: } else {
359: throw new RegistryException(
360: mTranslator
361: .getString(
362: LocalStringKeys.JBI_ADMIN_REGISTRY_CORRUPT,
363: getRegistryFilePath(),
364: ex.getMessage(),
365: getRegistryBkupFilePath()));
366: }
367: }
368: }
369: } catch (SAXException se) {
370: se.printStackTrace();
371:
372: String errMsg = mTranslator
373: .getString(
374: LocalStringKeys.JBI_ADMIN_REGISTRY_CREATION_FAILED,
375: se.toString());
376: throw new RegistryException(errMsg, se);
377:
378: } catch (JAXBException ex) {
379: ex.printStackTrace();
380:
381: String errMsg = mTranslator
382: .getString(
383: LocalStringKeys.JBI_ADMIN_REGISTRY_CREATION_FAILED,
384: ex.toString());
385: throw new RegistryException(errMsg, ex);
386:
387: } catch (java.io.IOException ex) {
388: ex.printStackTrace();
389: String errMsg = mTranslator
390: .getString(
391: LocalStringKeys.JBI_ADMIN_REGISTRY_CREATION_FAILED,
392: ex.toString());
393: throw new RegistryException(errMsg, ex);
394: }
395: }
396:
397: return mJbiRegistry;
398: }
399:
400: /**
401: * Load the Registry information and validate it.
402: *
403: * @throws java.io.IOException
404: * @throws JAXBException
405: */
406: private synchronized void loadPrimaryRegistry()
407: throws java.io.FileNotFoundException, JAXBException {
408: File registryFile = new File(getRegistryFilePath());
409: try {
410: Unmarshaller u = sJC.createUnmarshaller();
411:
412: u.setSchema(javax.xml.validation.SchemaFactory.newInstance(
413: javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)
414: .newSchema(mRegSchema));
415:
416: FileInputStream fis = new FileInputStream(registryFile);
417: mJbiRegistry = (Jbi) u.unmarshal(fis);
418: try {
419: fis.close();
420: } catch (java.io.IOException ioex) {
421: mLogger.warning(ioex.toString());
422: }
423:
424: } catch (SAXException se) {
425: se.printStackTrace();
426: String errMsg = mTranslator.getString(
427: LocalStringKeys.JBI_ADMIN_INVALID_REGISTRY_FORMAT,
428: se.toString());
429: throw new JAXBException(errMsg, se);
430: } catch (JAXBException ex) {
431: File errFile = new File(mErrorFolderPath + File.separator
432: + "registry-" + System.currentTimeMillis() + ".xml");
433: movetoErrFile(registryFile, errFile);
434: throw ex;
435: }
436: }
437:
438: /**
439: * Take a back-up of a bad registry file in a err file
440: */
441: private void movetoErrFile(File origFile, File errFile) {
442:
443: File errFolder = new File(mErrorFolderPath);
444: if (!errFolder.exists()) {
445: FileHelper.createFolder(errFolder);
446: }
447:
448: if (!origFile.renameTo(errFile)) {
449: mLogger
450: .warning(mTranslator
451: .getString(
452: LocalStringKeys.JBI_ADMIN_REGISTRY_FILE_RENAME_FAILED,
453: origFile.getAbsolutePath(), errFile
454: .getAbsolutePath()));
455: }
456: }
457:
458: /**
459: * @throws JAXBException if backup file is corrupted / invalid
460: * @throws java.io.IOException
461: */
462: private synchronized void loadBackupRegistry()
463: throws java.io.IOException, JAXBException {
464: File bkupFile = new File(mRegistryBackupFilePath);
465: File regFile = new File(getRegistryFilePath());
466: Date lastModified = new Date(bkupFile.lastModified());
467:
468: mLogger.warning(mTranslator.getString(
469: LocalStringKeys.JBI_ADMIN_REGISTRY_USING_BKUP,
470: mRegistryBackupFilePath, DateFormat
471: .getDateTimeInstance().format(lastModified)));
472:
473: // -- Move the back-up data to the main file
474: if (!bkupFile.renameTo(regFile)) {
475: String errMsg = mTranslator
476: .getString(
477: LocalStringKeys.JBI_ADMIN_REGISTRY_FILE_RENAME_FAILED,
478: mRegistryBackupFilePath, mRegistryFilePath);
479:
480: throw new java.io.IOException(errMsg);
481: }
482:
483: try {
484:
485: Unmarshaller u = sJC.createUnmarshaller();
486: u.setSchema(javax.xml.validation.SchemaFactory.newInstance(
487: javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)
488: .newSchema(mRegSchema));
489:
490: FileInputStream fis = new FileInputStream(regFile);
491: mJbiRegistry = (Jbi) u.unmarshal(fis);
492: try {
493: fis.close();
494: } catch (java.io.IOException ioex) {
495: mLogger.warning(ioex.toString());
496: }
497:
498: } catch (SAXException se) {
499: se.printStackTrace();
500: String errMsg = mTranslator.getString(
501: LocalStringKeys.JBI_ADMIN_INVALID_REGISTRY_FORMAT,
502: se.toString());
503: throw new JAXBException(errMsg, se);
504:
505: }
506: }
507:
508: /**
509: * Fresh start-up. Create the Primary registry file.
510: * @throws RegistryException
511: */
512: private synchronized void createPrimaryRegistry()
513: throws RegistryException {
514:
515: try {
516: File registryFile = new File(mRegistryFilePath);
517:
518: mLogger.fine(mTranslator.getString(
519: LocalStringKeys.JBI_ADMIN_REGISTRY_CREATE,
520: mRegistryFilePath));
521:
522: FileHelper.createFile(registryFile);
523: // -- Create the Esb Configuration from scratch
524: ObjectFactory factory = new ObjectFactory();
525: mJbiRegistry = (Jbi) new ObjectFactory().createJbi();
526:
527: // -- Add empty Instances, Components, Shared Libraries
528: // -- and Service Assemblies
529: mJbiRegistry.setClusters(factory.createClusterListType());
530: mJbiRegistry.setServers(factory.createServerListType());
531: mJbiRegistry.setSharedLibraries(factory
532: .createSharedLibraries());
533: mJbiRegistry.setServiceAssemblies(factory
534: .createServiceAssemblies());
535: mJbiRegistry.setConfigs(factory.createConfigs());
536:
537: // -- Save the Changes
538: Writer wr = getRegistryWriter();
539: String validate = mProps.getProperty(VALIDATE, "false")
540: .toLowerCase();
541: if (Boolean.getBoolean(validate)) {
542: mMarshaller
543: .setSchema(javax.xml.validation.SchemaFactory
544: .newInstance(
545: javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)
546: .newSchema(mRegSchema));
547: }
548:
549: mMarshaller.marshal(mJbiRegistry, wr);
550: wr.close();
551: } catch (SAXException se) {
552: se.printStackTrace();
553: String errMsg = mTranslator
554: .getString(LocalStringKeys.JBI_ADMIN_INVALID_REGISTRY_OBJECT);
555: mLogger.severe(errMsg);
556: throw new RegistryException(errMsg);
557: } catch (Exception ex) {
558: ex.printStackTrace();
559: throw new RegistryException(mTranslator.getString(
560: LocalStringKeys.JBI_ADMIN_REGISTRY_CREATE_FAILED,
561: mRegistryFilePath, ex.getMessage()));
562:
563: }
564: }
565:
566: /**
567: * @return the Marshaller.
568: */
569: Marshaller getMarshaller() {
570: return mMarshaller;
571: }
572:
573: /**
574: * Get the Updater instance to be used for updating the Registry.
575: *
576: * @return an instance of the Updater to be used to manipulate
577: * ( create / delete / modify ) contents of the registry.
578: * @throws RegistryException if problems are encountered in creating
579: * a Updater.
580: */
581: public Updater getUpdater() throws RegistryException {
582: String validate = mProps.getProperty(VALIDATE, "false")
583: .toLowerCase();
584: initJbiRegistry();
585: return new UpdaterImpl(mJbiRegistry, mMgtCtx, Boolean
586: .getBoolean(validate), this );
587: }
588:
589: /**
590: * Get a Generic Query Instance
591: * @return an instance of GenericQuery.
592: * @throws RegistryException on errors.
593: */
594: public GenericQuery getGenericQuery() throws RegistryException {
595:
596: String validate = mProps.getProperty(VALIDATE, "false")
597: .toLowerCase();
598: initJbiRegistry();
599: return new GenericQueryImpl(mJbiRegistry, mMgtCtx, Boolean
600: .getBoolean(validate), this );
601: }
602:
603: /**
604: * Get a ComponentQuery instance for a given target
605: *
606: * @param targetName - name identifying the target.
607: * @return an instance of ComponentQuery.
608: * @throws RegistryException on errors.
609: */
610: public ComponentQuery getComponentQuery(String targetName)
611: throws RegistryException {
612: String validate = mProps.getProperty(VALIDATE, "false")
613: .toLowerCase();
614: initJbiRegistry();
615: return new ComponentQueryImpl(mJbiRegistry, mMgtCtx, Boolean
616: .getBoolean(validate), targetName, this );
617: }
618:
619: /**
620: * Get the ComponentQuery specific to the target of the instance.
621: *
622: * @return an instance of ComponentQuery.
623: * @throws RegistryException on errors.
624: */
625: public ComponentQuery getComponentQuery() throws RegistryException {
626: return getComponentQuery(mPlatform.getTargetName());
627: }
628:
629: /**
630: * Get a ServiceAssemblyQuery instance for a given target
631: *
632: * @param targetName - name identifying the target.
633: * @return an instance of ServiceAssemblyQuery.
634: * @throws RegistryException on errors.
635: */
636: public ServiceAssemblyQuery getServiceAssemblyQuery(
637: String targetName) throws RegistryException {
638: String validate = mProps.getProperty(VALIDATE, "false")
639: .toLowerCase();
640: initJbiRegistry();
641: return new ServiceAssemblyQueryImpl(mJbiRegistry, mMgtCtx,
642: Boolean.getBoolean(validate), targetName, this );
643: }
644:
645: /**
646: * Get the ServiceAssemblyQuery specific to the target of the instance.
647: *
648: * @return an instance of ServiceAssemblyQuery.
649: * @throws RegistryException on errors.
650: */
651: public ServiceAssemblyQuery getServiceAssemblyQuery()
652: throws RegistryException {
653: return getServiceAssemblyQuery(mPlatform.getTargetName());
654: }
655:
656: /**
657: * @return a Writer to the XML file.
658: */
659: Writer getRegistryWriter() {
660: OutputStreamWriter osw = null;
661: try {
662: FileOutputStream fos = new FileOutputStream(
663: getRegistryFile());
664: osw = new OutputStreamWriter(fos, "UTF8");
665: } catch (IOException ioe) {
666: ioe.printStackTrace();
667: }
668: return osw;
669: }
670:
671: /**
672: * @return a the Registry File reference.
673: */
674: public File getRegistryFile() {
675: File regFile = new File(mRegistryFilePath);
676:
677: if (!(regFile.exists())) {
678: FileHelper.createFile(regFile);
679: }
680: return regFile;
681: }
682:
683: /**
684: * @return the path to the Registry Folder
685: */
686: public String getRegistryFolderPath() {
687: return mRegistryFolderPath;
688: }
689:
690: /**
691: * @return the path to the Registry File
692: */
693: public String getRegistryFilePath() {
694: return mRegistryFilePath;
695: }
696:
697: /**
698: * @return the path to the Registry Backup File
699: */
700: public String getRegistryBkupFilePath() {
701: return mRegistryBackupFilePath;
702: }
703:
704: public ManagementContext getManagementContext() {
705: return mMgtCtx;
706: }
707:
708: public Repository getRepository() {
709: return mMgtCtx.getRepository();
710: }
711:
712: /**
713: * Get the Registry Specification.
714: */
715: public RegistrySpec getRegistrySpec() {
716: return mSpec;
717: }
718:
719: /**
720: * Get a Registry Property.
721: */
722: public String getProperty(String propName) {
723: if (propName.equals(Registry.REGISTRY_FILE_PROPERTY)) {
724: return (mRegistryFile);
725: } else if (propName
726: .equals(Registry.REGISTRY_SYNC_FILE_PROPERTY)) {
727: return (REGISTRY_SYNC_FILE);
728: } else if (propName.equals(Registry.REGISTRY_FOLDER_PROPERTY)) {
729: return (mRegistryFolderPath);
730: } else if (propName.equals(Registry.REGISTRY_READONLY_PROPERTY)) {
731: return (mProps
732: .getProperty(Registry.REGISTRY_READONLY_PROPERTY));
733: }
734: return (null);
735: }
736:
737: /**
738: * Commit the changes to the registry.
739: *
740: * @param validate - if true indicates that the Registry Content is
741: * to be validated.
742: */
743: public void commit() throws RegistryException {
744: boolean regFileBackedUp = false;
745:
746: File backupFile = new File(this .getRegistryBkupFilePath());
747: File regFile = new File(this .getRegistryFilePath());
748:
749: try {
750: mSerializationRWLockManager.acquireWriteLock();
751:
752: if (backupFile.exists()) {
753: if (!backupFile.delete()) {
754: mLogger
755: .warning(mTranslator
756: .getString(
757: LocalStringKeys.JBI_ADMIN_REGISTRY_FILE_DELETE_FAILED,
758: this
759: .getRegistryBkupFilePath()));
760: }
761: }
762:
763: if (!regFile.renameTo(backupFile)) {
764: mLogger
765: .warning(mTranslator
766: .getString(
767: LocalStringKeys.JBI_ADMIN_REGISTRY_FILE_RENAME_FAILED,
768: this .getRegistryBkupFilePath(),
769: this .getRegistryFilePath()));
770: } else {
771: regFileBackedUp = true;
772: }
773:
774: Writer wr = this .getRegistryWriter();
775: mMarshaller.marshal(mJbiRegistry, wr);
776: wr.close();
777: } catch (Exception ex) {
778:
779: // -- Restore the registry file if backed up
780: if (regFileBackedUp) {
781: backupFile.renameTo(regFile);
782: }
783:
784: // -- Revert to the last good state
785: this .reinitialize();
786:
787: mSerializationRWLockManager.releaseWriteLock();
788: String errMsg = mTranslator
789: .getString(
790: LocalStringKeys.JBI_ADMIN_FAILED_SERIALIZE_REGISTRY,
791: ex.toString());
792: ex.printStackTrace();
793: mLogger.severe(errMsg);
794: throw new RegistryException(errMsg);
795: } finally {
796: mSerializationRWLockManager.releaseWriteLock();
797: }
798: }
799:
800: /**
801: * Take a consistent snapshot of the registry.
802: *
803: */
804: public ByteArrayInputStream snapshot() throws RegistryException {
805: try {
806: mSerializationRWLockManager.acquireWriteLock();
807: ByteArrayOutputStream baos = new ByteArrayOutputStream();
808:
809: mMarshaller.marshal(mJbiRegistry, baos);
810: baos.flush();
811: baos.close();
812: return (new ByteArrayInputStream(baos.toByteArray()));
813: } catch (Exception ex) {
814: String errMsg = mTranslator
815: .getString(
816: LocalStringKeys.JBI_ADMIN_FAILED_SERIALIZE_REGISTRY,
817: ex.toString());
818: ex.printStackTrace();
819: mLogger.severe(errMsg);
820: throw new RegistryException(errMsg);
821: } finally {
822: mSerializationRWLockManager.releaseWriteLock();
823: }
824: }
825:
826: /**
827: * @return the Read / Write Lock Manager used to synchronize access to the in-memory
828: * registry.
829: */
830: LockManager getRegistryObjectLockManager() {
831: return mRegistryObjRWLockManager;
832: }
833:
834: /**
835: * @return the Read / Write Lock Manager used to synchronize access to the serialized
836: * registry.
837: */
838: LockManager getSerializationLockManager() {
839: return mSerializationRWLockManager;
840: }
841:
842: }
|