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 com.tc.lang.TCThreadGroup;
008: import com.tc.object.bytecode.Manageable;
009: import com.tc.object.dna.api.DNA;
010: import com.tc.util.UnsafeUtil;
011:
012: import java.io.IOException;
013: import java.lang.reflect.Array;
014: import java.lang.reflect.Constructor;
015: import java.lang.reflect.InvocationTargetException;
016:
017: /**
018: * @author orion
019: */
020: public class TCObjectFactoryImpl implements TCObjectFactory {
021: private final static Object[] EMPTY_OBJECT_ARRAY = new Object[] {};
022:
023: private ClientObjectManager objectManager;
024: private final TCClassFactory clazzFactory;
025:
026: public TCObjectFactoryImpl(TCClassFactory clazzFactory) {
027: this .clazzFactory = clazzFactory;
028: }
029:
030: public void setObjectManager(ClientObjectManager objectManager) {
031: this .objectManager = objectManager;
032: }
033:
034: public TCObject getNewInstance(ObjectID id, Object peer, Class clazz) {
035: TCClass tcc = clazzFactory.getOrCreate(clazz, objectManager);
036: TCObject rv = tcc.createTCObject(id, peer);
037:
038: if (peer instanceof Manageable) {
039: ((Manageable) peer).__tc_managed(rv);
040: }
041:
042: return rv;
043: }
044:
045: public TCObject getNewInstance(ObjectID id, Class clazz) {
046: return getNewInstance(id, null, clazz);
047: }
048:
049: public Object getNewPeerObject(TCClass type, DNA dna)
050: throws IOException, ClassNotFoundException {
051: return type.getNewInstanceFromNonDefaultConstructor(dna);
052: }
053:
054: public Object getNewPeerObject(TCClass type, Object parent)
055: throws IllegalArgumentException, SecurityException,
056: InstantiationException, IllegalAccessException,
057: InvocationTargetException, NoSuchMethodException {
058: // This one is for non-static inner classes
059: return getNewPeerObject(type.getConstructor(),
060: EMPTY_OBJECT_ARRAY, type, parent);
061: }
062:
063: public Object getNewArrayInstance(TCClass type, int size) {
064: return Array.newInstance(type.getComponentType(), size);
065: }
066:
067: public Object getNewPeerObject(TCClass type)
068: throws IllegalArgumentException, InstantiationException,
069: IllegalAccessException, InvocationTargetException,
070: SecurityException, NoSuchMethodException {
071: Constructor ctor = type.getConstructor();
072: if (ctor == null)
073: throw new AssertionError("type:" + type.getName());
074: return getNewPeerObject(ctor, EMPTY_OBJECT_ARRAY, type, null);
075: }
076:
077: private Object getNewPeerObject(Constructor ctor, Object[] args,
078: TCClass type, Object parent)
079: throws IllegalArgumentException, InstantiationException,
080: IllegalAccessException, InvocationTargetException {
081: final Object rv;
082:
083: // XXX: hack to workaround issue with commons logging dependence on context loader
084: final Thread thread = Thread.currentThread();
085: final ClassLoader prevLoader = thread.getContextClassLoader();
086: final boolean adjustTCL = TCThreadGroup
087: .currentThreadInTCThreadGroup();
088:
089: if (adjustTCL) {
090: ClassLoader newTcl = type.getPeerClass().getClassLoader();
091: if (newTcl == null) {
092: // XXX: workaround jboss bug: http://jira.jboss.com/jira/browse/JBAS-4437
093: newTcl = ClassLoader.getSystemClassLoader();
094: }
095: thread.setContextClassLoader(newTcl);
096: }
097:
098: try {
099: rv = ctor.newInstance(args);
100: if (parent != null) {
101: UnsafeUtil.setField(rv, type.getParentField(), parent);
102: }
103: } finally {
104: if (adjustTCL)
105: thread.setContextClassLoader(prevLoader);
106: }
107: return rv;
108: }
109:
110: }
|