Source Code Cross Referenced for TCObjectImpl.java in  » Net » Terracotta » com » tc » object » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » Terracotta » com.tc.object 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003:         * notice. All rights reserved.
004:         */
005:        package com.tc.object;
006:
007:        import bsh.EvalError;
008:        import bsh.Interpreter;
009:        import bsh.ParseException;
010:
011:        import com.tc.lang.TCThreadGroup;
012:        import com.tc.logging.CustomerLogging;
013:        import com.tc.logging.TCLogger;
014:        import com.tc.logging.TCLogging;
015:        import com.tc.object.bytecode.Manageable;
016:        import com.tc.object.bytecode.TransparentAccess;
017:        import com.tc.object.dna.api.DNA;
018:        import com.tc.object.dna.api.DNAException;
019:        import com.tc.object.dna.api.DNAWriter;
020:        import com.tc.object.field.TCField;
021:        import com.tc.util.Assert;
022:        import com.tc.util.Conversion;
023:        import com.tc.util.Util;
024:
025:        import gnu.trove.TLinkable;
026:
027:        import java.io.IOException;
028:        import java.lang.ref.ReferenceQueue;
029:        import java.lang.ref.WeakReference;
030:
031:        /**
032:         * Implementation of TCObject interface.
033:         * <p>
034:         */
035:        public abstract class TCObjectImpl implements  TCObject {
036:            private static final TCLogger logger = TCLogging
037:                    .getLogger(TCObjectImpl.class);
038:
039:            private static final int ACCESSED_OFFSET = 1;
040:            private static final int IS_NEW_OFFSET = 2;
041:            private static final int AUTOLOCKS_DISABLED_OFFSET = 4;
042:            private static final int EVICTION_IN_PROGRESS_OFFSET = 8;
043:            private static final int NEW_DEHYDRATE_IN_PROGRESS_OFFSET = 16;
044:
045:            // XXX::This initial negative version number is important since GID is assigned in the server from 0.
046:            private long version = -1;
047:
048:            private final ObjectID objectID;
049:            protected final TCClass tcClazz;
050:            private WeakReference peerObject;
051:            private TLinkable next;
052:            private TLinkable previous;
053:            private byte flags = 0;
054:            private static final TCLogger consoleLogger = CustomerLogging
055:                    .getConsoleLogger();
056:
057:            protected TCObjectImpl(ReferenceQueue queue, ObjectID id,
058:                    Object peer, TCClass clazz) {
059:                this .objectID = id;
060:                this .tcClazz = clazz;
061:                setPeerObject(new WeakObjectReference(id, peer, queue));
062:            }
063:
064:            public boolean isShared() {
065:                return true;
066:            }
067:
068:            public boolean isNull() {
069:                return peerObject == null || getPeerObject() == null;
070:            }
071:
072:            public ObjectID getObjectID() {
073:                return objectID;
074:            }
075:
076:            protected ClientObjectManager getObjectManager() {
077:                return tcClazz.getObjectManager();
078:            }
079:
080:            public Object getPeerObject() {
081:                return peerObject.get();
082:            }
083:
084:            protected void setPeerObject(WeakReference pojo) {
085:                this .peerObject = pojo;
086:                Object realPojo;
087:                if ((realPojo = peerObject.get()) instanceof  Manageable) {
088:                    Manageable m = (Manageable) realPojo;
089:                    m.__tc_managed(this );
090:                }
091:            }
092:
093:            public TCClass getTCClass() {
094:                return tcClazz;
095:            }
096:
097:            /**
098:             * Reconstitutes the object using the data in the DNA strand. XXX: We may need to signal (via a different signature or
099:             * args) that the hydration is intended to initialize the object from scratch or if it's a delta. We must avoid
100:             * creating a new instance of the peer object if the strand is just a delta.
101:             *
102:             * @throws ClassNotFoundException
103:             */
104:            public void hydrate(DNA from, boolean force)
105:                    throws ClassNotFoundException {
106:                synchronized (getResolveLock()) {
107:                    boolean isNewLoad = isNull();
108:                    createPeerObjectIfNecessary(from);
109:
110:                    Object po = getPeerObject();
111:                    if (po == null)
112:                        return;
113:                    try {
114:                        tcClazz.hydrate(this , from, po, force);
115:                        if (isNewLoad)
116:                            performOnLoadActionIfNecessary(po);
117:                    } catch (ClassNotFoundException e) {
118:                        logger.warn("Re-throwing Exception: ", e);
119:                        throw e;
120:                    } catch (IOException e) {
121:                        logger.warn("Re-throwing Exception: ", e);
122:                        throw new DNAException(e);
123:                    }
124:                }
125:            }
126:
127:            private void performOnLoadActionIfNecessary(Object pojo) {
128:                TCClass tcc = getTCClass();
129:                if (tcc.hasOnLoadExecuteScript() || tcc.hasOnLoadMethod()) {
130:                    String eval = tcc.hasOnLoadExecuteScript() ? tcc
131:                            .getOnLoadExecuteScript() : "self."
132:                            + tcc.getOnLoadMethod() + "()";
133:                    resolveAllReferences();
134:
135:                    final ClassLoader prevLoader = Thread.currentThread()
136:                            .getContextClassLoader();
137:                    final boolean adjustTCL = TCThreadGroup
138:                            .currentThreadInTCThreadGroup();
139:
140:                    if (adjustTCL) {
141:                        ClassLoader newTCL = pojo.getClass().getClassLoader();
142:                        if (newTCL == null)
143:                            newTCL = ClassLoader.getSystemClassLoader();
144:                        Thread.currentThread().setContextClassLoader(newTCL);
145:                    }
146:
147:                    try {
148:                        Interpreter i = new Interpreter();
149:                        i.setClassLoader(tcc.getPeerClass().getClassLoader());
150:                        i.set("self", pojo);
151:                        i.eval("setAccessibility(true)");
152:                        i.eval(eval);
153:                    } catch (ParseException e) {
154:                        // Error Parsing script. Use e.getMessage() instead of e.getErrorText() when there is a ParseException because
155:                        // expectedTokenSequences in ParseException could be null and thus, may throw a NullPointerException when
156:                        // calling
157:                        // e.getErrorText().
158:                        consoleLogger.error("Unable to parse OnLoad script: "
159:                                + pojo.getClass() + " error: " + e.getMessage()
160:                                + " stack: " + e.getScriptStackTrace());
161:                        logger.error("Unable to parse OnLoad script: "
162:                                + pojo.getClass() + " error: " + e.getMessage()
163:                                + " line: " + " stack: "
164:                                + e.getScriptStackTrace());
165:                    } catch (EvalError e) {
166:                        // General Error evaluating script
167:                        consoleLogger
168:                                .error("OnLoad execute script failed for: "
169:                                        + pojo.getClass() + " error: "
170:                                        + e.getErrorText() + " line: "
171:                                        + e.getErrorLineNumber() + "; "
172:                                        + e.getMessage() + "; stack: "
173:                                        + e.getScriptStackTrace());
174:                        logger.error("OnLoad execute script failed for: "
175:                                + pojo.getClass() + " error: "
176:                                + e.getErrorText() + " line: "
177:                                + e.getErrorLineNumber() + "; "
178:                                + e.getMessage() + "; stack: "
179:                                + e.getScriptStackTrace());
180:                    } finally {
181:                        if (adjustTCL)
182:                            Thread.currentThread().setContextClassLoader(
183:                                    prevLoader);
184:                    }
185:                }
186:            }
187:
188:            protected synchronized void setFlag(int offset, boolean value) {
189:                flags = Conversion.setFlag(flags, offset, value);
190:            }
191:
192:            private synchronized boolean getFlag(int offset) {
193:                return Conversion.getFlag(flags, offset);
194:            }
195:
196:            private void createPeerObjectIfNecessary(DNA from) {
197:                if (isNull()) {
198:                    // TODO: set created and modified version id
199:                    setPeerObject(getObjectManager().createNewPeer(tcClazz,
200:                            from));
201:                }
202:            }
203:
204:            public ObjectID setReference(String fieldName, ObjectID id) {
205:                throw new AssertionError("shouldn't be called");
206:            }
207:
208:            public void setArrayReference(int index, ObjectID id) {
209:                throw new AssertionError("shouldn't be called");
210:            }
211:
212:            public void setValue(String fieldName, Object obj) {
213:                try {
214:                    TransparentAccess ta = (TransparentAccess) getPeerObject();
215:                    if (ta == null) {
216:                        // Object was GC'd so return which should lead to a re-retrieve
217:                        return;
218:                    }
219:                    clearReference(fieldName);
220:                    TCField field = getTCClass().getField(fieldName);
221:                    if (field == null) {
222:                        logger
223:                                .warn("Data for field:"
224:                                        + fieldName
225:                                        + " was recieved but that field does not exist in class:");
226:                        return;
227:                    }
228:                    if (obj instanceof  ObjectID) {
229:                        setReference(fieldName, (ObjectID) obj);
230:                        if (!field.isFinal()) {
231:                            ta.__tc_setfield(field.getName(), null);
232:                        }
233:                    } else {
234:                        // clean this up
235:                        ta.__tc_setfield(field.getName(), obj);
236:                    }
237:                } catch (Exception e) {
238:                    // TODO: More elegant exception handling.
239:                    throw new com.tc.object.dna.api.DNAException(e);
240:                }
241:            }
242:
243:            public int clearReferences(int toClear) {
244:                synchronized (getResolveLock()) {
245:                    try {
246:                        Object po = getPeerObject();
247:                        Assert.assertFalse(isNew()); // Shouldnt clear new Objects
248:                        if (po == null)
249:                            return 0;
250:                        return clearReferences(po, toClear);
251:                    } finally {
252:                        setEvictionInProgress(false);
253:                    }
254:                }
255:            }
256:
257:            protected abstract int clearReferences(Object pojo, int toClear);
258:
259:            public final Object getResolveLock() {
260:                return objectID; // Save a field by using this one as the lock
261:            }
262:
263:            public void resolveArrayReference(int index) {
264:                throw new AssertionError("shouldn't be called");
265:            }
266:
267:            public ArrayIndexOutOfBoundsException checkArrayIndex(int index) {
268:                throw new AssertionError("shouldn't be called");
269:            }
270:
271:            public void clearArrayReference(int index) {
272:                clearReference(Integer.toString(index));
273:            }
274:
275:            public void clearReference(String fieldName) {
276:                // do nothing
277:            }
278:
279:            public void resolveReference(String fieldName) {
280:                // do nothing
281:            }
282:
283:            public void resolveAllReferences() {
284:                // override me
285:            }
286:
287:            public void literalValueChanged(Object newValue, Object oldValue) {
288:                throw new UnsupportedOperationException();
289:            }
290:
291:            public void setLiteralValue(Object newValue) {
292:                throw new UnsupportedOperationException();
293:            }
294:
295:            /**
296:             * Writes the data in the object to the DNA writer supplied.
297:             */
298:            public boolean dehydrateIfNew(DNAWriter writer) throws DNAException {
299:                final boolean dehydrate;
300:
301:                // We use 2 flags here, we can't hold the lock on "this"
302:                // while dehydrating (CDV-479). Introducing another lock would work, but would
303:                // require adding a field to TCObjectImpl (which is a no-no memory wise)
304:                synchronized (this ) {
305:                    dehydrate = isNew()
306:                            && !getFlag(NEW_DEHYDRATE_IN_PROGRESS_OFFSET);
307:
308:                    if (dehydrate) {
309:                        setFlag(NEW_DEHYDRATE_IN_PROGRESS_OFFSET, true);
310:                    }
311:                }
312:
313:                // Flipping the "new" flag must occur AFTER dehydrate -- otherwise the client
314:                // memory manager might start nulling field values! (see canEvict() dependency on isNew() condition)
315:                if (dehydrate) {
316:                    tcClazz.dehydrate(this , writer, getPeerObject());
317:                    setFlag(IS_NEW_OFFSET, false);
318:                    setFlag(NEW_DEHYDRATE_IN_PROGRESS_OFFSET, false);
319:                }
320:
321:                return dehydrate;
322:            }
323:
324:            public synchronized void setVersion(long version) {
325:                this .version = version;
326:            }
327:
328:            public synchronized long getVersion() {
329:                return this .version;
330:            }
331:
332:            public String toString() {
333:                return getClass().getName() + "@"
334:                        + System.identityHashCode(this ) + "[objectID="
335:                        + objectID + ", TCClass=" + tcClazz + "]";
336:            }
337:
338:            public void objectFieldChanged(String classname, String fieldname,
339:                    Object newValue, int index) {
340:                try {
341:                    this .markAccessed();
342:                    if (index == NULL_INDEX) {
343:                        // Assert.eval(fieldname.indexOf('.') >= 0);
344:                        clearReference(fieldname);
345:                    } else {
346:                        clearArrayReference(index);
347:                    }
348:                    getObjectManager().getTransactionManager().fieldChanged(
349:                            this , classname, fieldname, newValue, index);
350:                } catch (Throwable t) {
351:                    Util.printLogAndRethrowError(t, logger);
352:                }
353:            }
354:
355:            public void objectFieldChangedByOffset(String classname,
356:                    long fieldOffset, Object newValue, int index) {
357:                String fieldname = tcClazz.getFieldNameByOffset(fieldOffset);
358:                objectFieldChanged(classname, fieldname, newValue, index);
359:            }
360:
361:            public boolean isFieldPortableByOffset(long fieldOffset) {
362:                return tcClazz.isPortableField(fieldOffset);
363:            }
364:
365:            public String getFieldNameByOffset(long fieldOffset) {
366:                return tcClazz.getFieldNameByOffset(fieldOffset);
367:            }
368:
369:            public void booleanFieldChanged(String classname, String fieldname,
370:                    boolean newValue, int index) {
371:                objectFieldChanged(classname, fieldname, new Boolean(newValue),
372:                        index);
373:            }
374:
375:            public void byteFieldChanged(String classname, String fieldname,
376:                    byte newValue, int index) {
377:                objectFieldChanged(classname, fieldname, new Byte(newValue),
378:                        index);
379:            }
380:
381:            public void charFieldChanged(String classname, String fieldname,
382:                    char newValue, int index) {
383:                objectFieldChanged(classname, fieldname,
384:                        new Character(newValue), index);
385:            }
386:
387:            public void doubleFieldChanged(String classname, String fieldname,
388:                    double newValue, int index) {
389:                objectFieldChanged(classname, fieldname, new Double(newValue),
390:                        index);
391:            }
392:
393:            public void floatFieldChanged(String classname, String fieldname,
394:                    float newValue, int index) {
395:                objectFieldChanged(classname, fieldname, new Float(newValue),
396:                        index);
397:            }
398:
399:            public void intFieldChanged(String classname, String fieldname,
400:                    int newValue, int index) {
401:                objectFieldChanged(classname, fieldname, new Integer(newValue),
402:                        index);
403:            }
404:
405:            public void longFieldChanged(String classname, String fieldname,
406:                    long newValue, int index) {
407:                objectFieldChanged(classname, fieldname, new Long(newValue),
408:                        index);
409:            }
410:
411:            public void shortFieldChanged(String classname, String fieldname,
412:                    short newValue, int index) {
413:                objectFieldChanged(classname, fieldname, new Short(newValue),
414:                        index);
415:            }
416:
417:            public void objectArrayChanged(int startPos, Object[] array,
418:                    int length) {
419:                this .markAccessed();
420:                for (int i = 0; i < length; i++) {
421:                    clearArrayReference(startPos + i);
422:                }
423:                getObjectManager().getTransactionManager().arrayChanged(this ,
424:                        startPos, array, length);
425:            }
426:
427:            public void primitiveArrayChanged(int startPos, Object array,
428:                    int length) {
429:                this .markAccessed();
430:                getObjectManager().getTransactionManager().arrayChanged(this ,
431:                        startPos, array, length);
432:            }
433:
434:            public void setNext(TLinkable link) {
435:                this .next = link;
436:            }
437:
438:            public void setPrevious(TLinkable link) {
439:                this .previous = link;
440:            }
441:
442:            public TLinkable getNext() {
443:                return this .next;
444:            }
445:
446:            public TLinkable getPrevious() {
447:                return this .previous;
448:            }
449:
450:            public void markAccessed() {
451:                setFlag(ACCESSED_OFFSET, true);
452:            }
453:
454:            public void clearAccessed() {
455:                setFlag(ACCESSED_OFFSET, false);
456:            }
457:
458:            public boolean recentlyAccessed() {
459:                return getFlag(ACCESSED_OFFSET);
460:            }
461:
462:            public int accessCount(int factor) {
463:                // TODO:: Implement when needed
464:                throw new UnsupportedOperationException();
465:            }
466:
467:            public synchronized void setIsNew() {
468:                if (getFlag(IS_NEW_OFFSET)) {
469:                    throw new IllegalStateException("new flag already set");
470:                }
471:                setFlag(IS_NEW_OFFSET, true);
472:            }
473:
474:            public boolean isNew() {
475:                return getFlag(IS_NEW_OFFSET);
476:            }
477:
478:            // These autlocking disable methods are checked in ManagerImpl. The one known use case
479:            // is the Hashtable used to hold sessions. We need local synchronization,
480:            // but we don't ever want autolocks for that particular instance
481:            public void disableAutoLocking() {
482:                setFlag(AUTOLOCKS_DISABLED_OFFSET, true);
483:            }
484:
485:            public boolean autoLockingDisabled() {
486:                return getFlag(AUTOLOCKS_DISABLED_OFFSET);
487:            }
488:
489:            private void setEvictionInProgress(boolean value) {
490:                setFlag(EVICTION_IN_PROGRESS_OFFSET, value);
491:            }
492:
493:            private boolean isEvictionInProgress() {
494:                return getFlag(EVICTION_IN_PROGRESS_OFFSET);
495:            }
496:
497:            public synchronized boolean canEvict() {
498:                boolean canEvict = isEvictable()
499:                        && !(isNew() || isEvictionInProgress());
500:                if (canEvict) {
501:                    setEvictionInProgress(true);
502:                }
503:                return canEvict;
504:            }
505:
506:            protected abstract boolean isEvictable();
507:
508:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.