001: // You can redistribute this software and/or modify it under the terms of
002: // the Ozone Library License version 1 published by ozone-db.org.
003: //
004: // The original code and portions created by SMB are
005: // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
006: //
007: // $Id: Database.java,v 1.3 2002/06/08 00:49:38 mediumnet Exp $
008:
009: package org.ozoneDB;
010:
011: import org.ozoneDB.core.DbRemote.CommandThread;
012: import org.ozoneDB.core.DbRemote.DbXMLForObj;
013: import org.ozoneDB.core.*;
014: import org.ozoneDB.util.LogWriter;
015: import org.ozoneDB.xml.util.SAXChunkConsumer;
016: import org.w3c.dom.Document;
017: import org.w3c.dom.Node;
018: import org.xml.sax.ContentHandler;
019:
020: /**
021: * This class represents the database for OzoneObjects within the server.<p>
022: *
023: * Note: The method parameters of type {@link OzoneRemote} are supposed to by
024: * proxy objects (of type {@link OzoneProxy}). However, since we are inside the
025: * server it's possible to pass an database object (of type {@link
026: * OzoneCompatible}) as a parameter. In this case the parameter should be
027: * substituted. Currently this is done by the invoke() method only.
028: *
029: * @author <a href="http://www.softwarebuero.de/">SMB</a>
030: * @author <a href="http://www.medium.net/">Medium.net</a>
031: * @version $Revision: 1.3 $Date: 2002/06/08 00:49:38 $
032: * @see OzoneInterface
033: */
034: public final class Database extends AbstractDatabase implements
035: OzoneInterface {
036:
037: protected transient Env env;
038:
039: public Database() {
040: }
041:
042: public Database(Env _env) {
043: env = _env;
044: }
045:
046: public void reloadClasses() throws Exception {
047: throw new Exception(
048: "reloadClasses() must not be called from within the server.");
049: }
050:
051: public User currentOwner() {
052: Thread thread = Thread.currentThread();
053: /*
054: if (thread instanceof Transaction) {
055: return ((Transaction)thread).owner();
056: }
057: */
058: if (thread instanceof CommandThread) {
059: return ((CommandThread) thread).owner();
060: } else {
061: env.fatalError(this ,
062: "Current thread is not a transaction or command!",
063: null);
064: return null;
065: }
066: }
067:
068: public OzoneProxy createObject(String className, int access,
069: String objName, String sig, Object[] args)
070: throws RuntimeException, ExceptionInOzoneObjectException {
071: // env.logWriter.newEntry( this, "createObject()...", LogWriter.DEBUG3 );
072: try {
073: ObjectContainer container = env.transactionManager
074: .currentTA().createObjectAndPin(className, access,
075: objName, sig, args, null);
076:
077: try {
078: OzoneProxy result = container.ozoneProxy();
079: // env.logWriter.newEntry ("return: " + result.getClass().getName(), LogWriter.DEBUG);
080: return result;
081: } finally {
082: container.unpin();
083: }
084: } catch (java.lang.reflect.InvocationTargetException e) {
085: throw new ExceptionInOzoneObjectException(
086: "Caught during deleteObject()", e
087: .getTargetException());
088: } catch (ExceptionInOzoneObjectException e) {
089: throw e;
090: } catch (Exception e) {
091: // only supported from JDK1.4 on
092: // throw new RuntimeException("Caught during createObject()",e);
093: env.logWriter.newEntry(this , "createObject(): caught", e,
094: LogWriter.DEBUG3);
095: throw new RuntimeException("Caught during createObject(): "
096: + e);
097: }
098: }
099:
100: public OzoneProxy copyObject(OzoneRemote rObj) throws Exception {
101: env.logWriter.newEntry(this , "copyObject()...",
102: LogWriter.DEBUG3);
103: ObjectContainer container = env.transactionManager.currentTA()
104: .copyObjectAndPin(((OzoneProxy) rObj).remoteID());
105: try {
106: return container.ozoneProxy();
107: } finally {
108: container.unpin();
109: }
110: }
111:
112: public void deleteObject(OzoneRemote rObj) throws RuntimeException,
113: ExceptionInOzoneObjectException {
114: try {
115: if (false) {
116: env.logWriter.newEntry(this , "deleteObject()...",
117: LogWriter.DEBUG3);
118: }
119: env.transactionManager.currentTA().deleteObject(
120: ((OzoneProxy) rObj).remoteID());
121: } catch (ExceptionInOzoneObjectException e) {
122: throw e;
123: } catch (Exception e) {
124: // only supported from JDK1.4 on
125: // throw new RuntimeException("Caught during deleteObject()",e);
126: throw new RuntimeException("Caught during deleteObject(): "
127: + e);
128: }
129: }
130:
131: public void nameObject(OzoneRemote rObj, String name)
132: throws Exception {
133: if (false) {
134: env.logWriter.newEntry(this , "nameObject()...",
135: LogWriter.DEBUG3);
136: }
137: env.transactionManager.currentTA().nameObject(
138: ((OzoneProxy) rObj).remoteID(), name);
139: }
140:
141: public OzoneProxy objectForName(String name) throws Exception {
142: env.logWriter.newEntry(this , "objectForName()... ",
143: LogWriter.DEBUG3);
144: return env.transactionManager.currentTA().objectForName(name);
145: }
146:
147: public OzoneProxy objectForHandle(String handle) throws Exception {
148: env.logWriter.newEntry(this , "objectForHandle()... ",
149: LogWriter.DEBUG3);
150: return env.transactionManager.currentTA().objectForID(
151: new ObjectID(handle));
152: }
153:
154: public OzoneProxy[] objectsOfClass(String name) throws Exception {
155: env.logWriter.newEntry(this , "objectsForClass()...",
156: LogWriter.DEBUG3);
157: throw new RuntimeException(
158: "objectsForClass(): not implemented.");
159: }
160:
161: public Object invoke(OzoneProxy rObj, String methodName,
162: String sig, Object[] args, int lockLevel) throws Exception {
163:
164: //one argument could have been "this", then we have to give
165: //a proxy instead of the actual object
166: for (int i = 0; i < args.length; i++) {
167: args[i] = ResultConverter
168: .substituteOzoneCompatibles(args[i]);
169: }
170:
171: Object result = env.transactionManager.currentTA()
172: .invokeObject(rObj.remoteID(), methodName, sig, args,
173: lockLevel);
174:
175: //also return could have been "this"...
176: result = ResultConverter.substituteOzoneCompatibles(result);
177: return result;
178: }
179:
180: public Object invoke(OzoneProxy rObj, int methodIndex,
181: Object[] args, int lockLevel) throws Exception {
182:
183: //one argument could have been "this", then we have to give
184: //a proxy instead of the actual object
185: for (int i = 0; i < args.length; i++) {
186: args[i] = ResultConverter
187: .substituteOzoneCompatibles(args[i]);
188: }
189:
190: Object result = env.transactionManager.currentTA()
191: .invokeObject(rObj.remoteID(), methodIndex, args,
192: lockLevel);
193:
194: //also return could have been "this"...
195: result = ResultConverter.substituteOzoneCompatibles(result);
196: return result;
197: }
198:
199: public OzoneCompatible fetch(OzoneProxy rObj, int lockLevel)
200: throws Exception {
201: // env.logWriter.newEntry (this, "fetch()...", LogWriter.DEBUG3);
202:
203: TransactionManager transactionManager = env.transactionManager;
204: Transaction currentTransaction = transactionManager.currentTA();
205: ObjectID id = rObj.remoteID();
206:
207: ObjectContainer container = currentTransaction
208: .acquireObjectAndPin(id, lockLevel);
209:
210: try {
211: return container.target();
212: } finally {
213: container.unpin();
214: }
215: }
216:
217: public Node xmlForObject(OzoneRemote rObj, Document domFactory)
218: throws Exception {
219:
220: // creating the chunk is not really needed but should work ;)
221: DbXMLForObj command = new DbXMLForObj((OzoneProxy) rObj);
222: command.perform(env.transactionManager.currentTA());
223: byte[] bytes = (byte[]) command.result;
224:
225: SAXChunkConsumer consumer = new SAXChunkConsumer(domFactory,
226: null);
227: consumer.processChunk(bytes);
228:
229: return consumer.getResultNode();
230: }
231:
232: public void xmlForObject(OzoneRemote rObj, ContentHandler ch)
233: throws Exception {
234:
235: // creating the chunk is not really needed but should work ;)
236: DbXMLForObj command = new DbXMLForObj((OzoneProxy) rObj);
237: command.perform(env.transactionManager.currentTA());
238: byte[] bytes = (byte[]) command.result;
239:
240: SAXChunkConsumer consumer = new SAXChunkConsumer(ch);
241: consumer.processChunk(bytes);
242: }
243:
244: /**
245: Internal method. This method is called by {@link OzoneProxy}s when they are dying (during finalize()). This
246: is required, as the database may track the references the database client has to objects within the database
247: in order to properly support garbage collection. If this method is called from anyone else than from the
248: {@link OzoneProxy}.finalize()-Method, data loss may occur!
249:
250: @param proxy the OzoneProxy object which is dying. It may call this method exaclty once.
251: */
252: public void notifyProxyDeath(OzoneProxy proxy) {
253: // We do nothing here as we do not care wether OzoneProxys within the local databases die.
254: }
255: }
|