001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.metamodel.adapter.oid;
021
022import java.io.IOException;
023import java.io.Serializable;
024
025import com.google.common.base.Objects;
026
027import org.apache.isis.core.commons.encoding.DataInputExtended;
028import org.apache.isis.core.commons.encoding.DataOutputExtended;
029import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
030
031/**
032 * Used as the {@link Oid} for collections.
033 */
034public final class CollectionOid extends ParentedOid implements Serializable {
035
036    private static final long serialVersionUID = 1L;
037
038    private final String name;
039    private int cachedHashCode;
040
041    // /////////////////////////////////////////////////////////
042    // Constructor
043    // /////////////////////////////////////////////////////////
044
045    public CollectionOid(TypedOid parentOid, OneToManyAssociation otma) {
046        this(parentOid, otma.getId());
047    }
048
049    public CollectionOid(TypedOid parentOid, String name) {
050        super(parentOid);
051        this.name = name;
052        cacheState();
053    }
054
055    
056    // /////////////////////////////////////////////////////////
057    // enstring
058    // /////////////////////////////////////////////////////////
059
060    public static CollectionOid deString(String oidStr, OidMarshaller oidMarshaller) {
061        return oidMarshaller.unmarshal(oidStr, CollectionOid.class);
062    }
063
064
065    @Override
066    public String enString(OidMarshaller oidMarshaller) {
067        return oidMarshaller.marshal(this);
068    }
069
070    @Override
071    public String enStringNoVersion(OidMarshaller oidMarshaller) {
072        return oidMarshaller.marshalNoVersion(this);
073    }
074
075
076    // /////////////////////////////////////////////////////////
077    // encodeable
078    // /////////////////////////////////////////////////////////
079
080
081    public CollectionOid(DataInputExtended inputStream) throws IOException {
082        this(CollectionOid.deString(inputStream.readUTF(), getEncodingMarshaller()));
083    }
084
085    private CollectionOid(CollectionOid oid) throws IOException {
086        super(oid.getParentOid());
087        this.name = oid.name;
088    }
089
090
091    @Override
092    public void encode(DataOutputExtended outputStream) throws IOException {
093        outputStream.writeUTF(enString(getEncodingMarshaller()));
094    }
095
096    /**
097     * Cannot be a reference because Oid gets serialized by wicket viewer
098     */
099    private static OidMarshaller getEncodingMarshaller() {
100        return new OidMarshaller();
101    }
102
103    // /////////////////////////////////////////////////////////
104    // Properties
105    // /////////////////////////////////////////////////////////
106
107    public String getName() {
108        return name;
109    }
110
111
112    // /////////////////////////////////////////////////////////
113    // Value semantics
114    // /////////////////////////////////////////////////////////
115
116    @Override
117    public boolean equals(final Object other) {
118        if (other == this) {
119            return true;
120        }
121        if (other == null) {
122            return false;
123        }
124        if (getClass() != other.getClass()) {
125            return false;
126        }
127        return equals((CollectionOid) other);
128    }
129
130    public boolean equals(final CollectionOid other) {
131        return Objects.equal(other.getParentOid(), getParentOid()) && Objects.equal(other.name, name);
132    }
133
134    
135    @Override
136    public int hashCode() {
137        cacheState();
138        return cachedHashCode;
139    }
140
141    private void cacheState() {
142        int hashCode = 17;
143        hashCode = 37 * hashCode + getParentOid().hashCode();
144        hashCode = 37 * hashCode + name.hashCode();
145        cachedHashCode = hashCode;
146    }
147
148
149    
150    // /////////////////////////////////////////////////////////
151    // asPersistent
152    // /////////////////////////////////////////////////////////
153
154    /**
155     * When the RootOid is persisted, all its "children"
156     * need updating similarly.
157     */
158    public CollectionOid asPersistent(TypedOid newParentRootOid) {
159        return new CollectionOid(newParentRootOid, name);
160    }
161
162
163
164
165}