001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  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
018package org.apache.wicket.model.util;
019
020import java.io.Serializable;
021
022import org.apache.wicket.model.IDetachable;
023import org.apache.wicket.model.IObjectClassAwareModel;
024import org.apache.wicket.util.lang.Objects;
025
026/**
027 * Base class for models that contain instances that do not appear to be serializable and cannot
028 * thus use <code>Model</code> directly. Makes sure that the object set into the model can be
029 * serialized.
030 * 
031 * @author Timo Rantalaiho
032 * @param <T>
033 *            type of model object
034 */
035public abstract class GenericBaseModel<T> implements IObjectClassAwareModel<T>
036{
037        private static final long serialVersionUID = 1L;
038        /** model object */
039        private T object;
040
041        @Override
042        public T getObject()
043        {
044                return object;
045        }
046
047        /**
048         * Set the model object. The contents must be serializable, as they are stored in the session
049         * 
050         * @param object
051         *            the model object
052         * @see org.apache.wicket.model.IModel#setObject(Object)
053         */
054        @Override
055        public void setObject(T object)
056        {
057                if (!(object instanceof Serializable))
058                {
059                        object = createSerializableVersionOf(object);
060                }
061                this.object = object;
062        }
063
064        /**
065         * Creates a serializable version of the object. The object is usually a collection.
066         * 
067         * @param object
068         * @return serializable version of <code>object</code>
069         */
070        protected abstract T createSerializableVersionOf(T object);
071
072        @Override
073        public void detach()
074        {
075                if (object instanceof IDetachable)
076                {
077                        ((IDetachable)object).detach();
078                }
079        }
080
081        @SuppressWarnings("unchecked")
082        @Override
083        public Class<T> getObjectClass()
084        {
085                return object != null ? (Class<T>) object.getClass() : null;
086        }
087
088        @Override
089        public String toString()
090        {
091         StringBuilder sb = new StringBuilder("Model:classname=[");
092                sb.append(getClass().getName()).append(']');
093                sb.append(":object=[").append(object).append(']');
094                return sb.toString();
095        }
096
097        @Override
098        public int hashCode()
099        {
100                return Objects.hashCode(object);
101        }
102
103        @Override
104        public boolean equals(Object obj)
105        {
106                if (this == obj)
107                {
108                        return true;
109
110                }
111                if (!(obj instanceof GenericBaseModel))
112                {
113                        return false;
114                }
115                GenericBaseModel<?> that = (GenericBaseModel<?>)obj;
116                return Objects.equal(object, that.object);
117        }
118}