001    package org.apache.ojb.odmg;
002    
003    /* Copyright 2002-2005 The Apache Software Foundation
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    import org.apache.ojb.broker.Identity;
019    import org.apache.ojb.broker.core.proxy.IndirectionHandler;
020    import org.apache.ojb.broker.core.proxy.ProxyHelper;
021    import org.apache.ojb.broker.metadata.ClassDescriptor;
022    import org.apache.commons.lang.builder.ToStringBuilder;
023    
024    /**
025     * Helper object encapsulates common used object properties/states, help to reduce
026     * needless metadata calls.
027     *
028     * @author <a href="mailto:arminw@apache.org">Armin Waibel</a>
029     * @version $Id: RuntimeObject.java,v 1.1 2007-08-24 22:17:37 ewestfal Exp $
030     */
031    public final class RuntimeObject
032    {
033        private final Object obj;
034        private Identity identity;
035        private final TransactionImpl tx;
036        private Boolean isNew;
037        private ClassDescriptor cld;
038        private IndirectionHandler handler;
039    
040        public RuntimeObject(final Object obj, final TransactionImpl tx)
041        {
042            this.tx = tx;
043            this.obj = obj;
044            initCld(tx);
045            doIsNewObjectCheck(tx);
046        }
047    
048        public RuntimeObject(final Object obj, final TransactionImpl tx, final boolean isNew)
049        {
050            this.tx = tx;
051            this.obj = obj;
052            this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
053            initCld(tx);
054        }
055    
056        public RuntimeObject(final Object obj, final Identity identity, final TransactionImpl tx, final boolean isNew)
057        {
058            this.tx = tx;
059            this.obj = obj;
060            this.identity = identity;
061            this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
062            initCld(tx);
063        }
064    
065        public RuntimeObject(final Object obj, final Identity oid, final ClassDescriptor cld, final boolean isNew, final boolean isProxy)
066        {
067            this.tx = null;
068            this.obj = obj;
069            this.identity = oid;
070            this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
071            this.cld = cld;
072            if(isProxy)
073            {
074                this.handler = ProxyHelper.getIndirectionHandler(obj);
075            }
076        }
077    
078        /*
079        try to avoid needless and unused method calls to provide
080        best performance, thus create Identity object only if needed
081        and do 'is new object' check only if needed.
082        */
083        private void initCld(final TransactionImpl tx)
084        {
085            final IndirectionHandler handler = ProxyHelper.getIndirectionHandler(obj);
086            if(handler != null)
087            {
088                this.handler = handler;
089                isNew = Boolean.FALSE;
090                identity = handler.getIdentity();
091                if(handler.alreadyMaterialized())
092                {
093                    cld = tx.getBroker().getClassDescriptor(handler.getRealSubject().getClass());
094                }
095                else
096                {
097                    cld = tx.getBroker().getClassDescriptor(identity.getObjectsRealClass());
098                }
099            }
100            else
101            {
102                cld = tx.getBroker().getClassDescriptor(obj.getClass());
103            }
104        }
105    
106        void doIsNewObjectCheck(final TransactionImpl tx)
107        {
108            boolean isNew = tx.isTransient(cld, obj, null);
109            this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
110        }
111    
112        /**
113         * Return the associated persistent object.
114         */
115        public Object getObj()
116        {
117            return obj;
118        }
119    
120        /**
121         * Returns the materialized object (if proxy is materialized or a "normal"
122         * persistent object) or <em>null</em> if associated with unmaterialized proxy object.
123         */
124        public Object getObjMaterialized()
125        {
126            return handler != null ? (handler.alreadyMaterialized() ? handler.getRealSubject() : null) : obj;
127        }
128    
129        /**
130         * Returns the associated object {@link org.apache.ojb.broker.Identity}.
131         */
132        public Identity getIdentity()
133        {
134            if(identity == null)
135            {
136                identity = tx.getBroker().serviceIdentity().buildIdentity(obj);
137            }
138            return identity;
139        }
140    
141        /**
142         * Returns the associated object {@link org.apache.ojb.broker.metadata.ClassDescriptor}.
143         */
144        public ClassDescriptor getCld()
145        {
146            return cld;
147        }
148    
149        /**
150         * Returns <code>true</code> if the represented object is
151         * not yet persisted.
152         */
153        public boolean isNew()
154        {
155            return isNew.booleanValue();
156        }
157    
158        public boolean isProxy()
159        {
160            return handler != null;
161        }
162    
163        public IndirectionHandler getHandler()
164        {
165            return handler;
166        }
167    
168        public String toString()
169        {
170            return new ToStringBuilder(this)
171                    .append("identity", identity)
172                    .append("isNew", isNew)
173                    .append("isProxy", handler != null)
174                    .append("handler", handler)
175                    .append("tx", tx)
176                    .toString();
177        }
178    }
179