001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Stephane Lacoin
018 */
019package org.nuxeo.ecm.core.api;
020
021import java.io.InvalidObjectException;
022import java.io.ObjectStreamException;
023import org.nuxeo.runtime.transaction.TransactionHelper;
024
025/**
026 * Document repository reference including the principal owner of the session.
027 *
028 * @since 7.10
029 * @author Stephane Lacoin at Nuxeo (aka matic)
030 */
031public class InstanceRef implements DocumentRef {
032
033    private static final long serialVersionUID = 1L;
034
035    final String repositoryName;
036
037    final NuxeoPrincipal principal;
038
039    final DocumentRef ref;
040
041    transient DocumentModel referent;
042
043    public InstanceRef(DocumentModel doc, NuxeoPrincipal principal) {
044        if (doc.getRef() == null) {
045            throw new NullPointerException("document as no reference yet");
046        }
047        referent = doc;
048        repositoryName = doc.getRepositoryName();
049        this.principal = principal;
050        ref = doc.getRef();
051    }
052
053    @Override
054    public int type() {
055        return -1;
056    }
057
058    @Override
059    public Object reference() {
060        return referent;
061    }
062
063    private Object readResolve() throws ObjectStreamException {
064        // we need a transaction for this
065        boolean started = false;
066        if (!TransactionHelper.isTransactionActiveOrMarkedRollback()) {
067            started = TransactionHelper.startTransaction();
068        }
069        try {
070            CoreSession session = CoreInstance.getCoreSession(repositoryName, principal);
071            referent = session.getDocument(ref);
072            referent.detach(true);
073            return referent;
074        } catch (RuntimeException cause) {
075            InvalidObjectException error = new InvalidObjectException(
076                    "Cannot refetch " + ref + " from " + repositoryName);
077            error.initCause(cause);
078            throw error;
079        } finally {
080            if (started) {
081                TransactionHelper.commitOrRollbackTransaction();
082            }
083        }
084    }
085
086    @Override
087    public int hashCode() {
088        final int prime = 31;
089        int result = 1;
090        result = prime * result + ((repositoryName == null) ? 0 : repositoryName.hashCode());
091        result = prime * result + ((ref == null) ? 0 : ref.hashCode());
092        result = prime * result + ((principal == null) ? 0 : principal.hashCode());
093        return result;
094    }
095
096    @Override
097    public boolean equals(Object obj) {
098        if (this == obj) {
099            return true;
100        }
101        if (obj == null) {
102            return false;
103        }
104        if (getClass() != obj.getClass()) {
105            return false;
106        }
107        InstanceRef other = (InstanceRef) obj;
108        if (repositoryName == null) {
109            if (other.repositoryName != null) {
110                return false;
111            }
112        } else if (!repositoryName.equals(other.repositoryName)) {
113            return false;
114        }
115        if (ref == null) {
116            if (other.ref != null) {
117                return false;
118            }
119        } else if (!ref.equals(other.ref)) {
120            return false;
121        }
122        if (principal == null) {
123            if (other.principal != null) {
124                return false;
125            }
126        } else if (!principal.equals(other.principal)) {
127            return false;
128        }
129        return true;
130    }
131}