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 java.security.Principal;
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 Principal principal;
038
039    final DocumentRef ref;
040
041    transient DocumentModel referent;
042
043    public InstanceRef(DocumentModel doc, Principal 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        try {
065            try (CoreSession session = CoreInstance.openCoreSession(repositoryName, principal)) {
066                referent = session.getDocument(ref);
067                referent.detach(true);
068                return referent;
069            }
070        } catch (RuntimeException cause) {
071            InvalidObjectException error = new InvalidObjectException(
072                    "Cannot refetch " + ref + " from " + repositoryName);
073            error.initCause(cause);
074            throw error;
075        }
076    }
077
078    @Override
079    public int hashCode() {
080        final int prime = 31;
081        int result = 1;
082        result = prime * result + ((repositoryName == null) ? 0 : repositoryName.hashCode());
083        result = prime * result + ((ref == null) ? 0 : ref.hashCode());
084        result = prime * result + ((principal == null) ? 0 : principal.hashCode());
085        return result;
086    }
087
088    @Override
089    public boolean equals(Object obj) {
090        if (this == obj) {
091            return true;
092        }
093        if (obj == null) {
094            return false;
095        }
096        if (getClass() != obj.getClass()) {
097            return false;
098        }
099        InstanceRef other = (InstanceRef) obj;
100        if (repositoryName == null) {
101            if (other.repositoryName != null) {
102                return false;
103            }
104        } else if (!repositoryName.equals(other.repositoryName)) {
105            return false;
106        }
107        if (ref == null) {
108            if (other.ref != null) {
109                return false;
110            }
111        } else if (!ref.equals(other.ref)) {
112            return false;
113        }
114        if (principal == null) {
115            if (other.principal != null) {
116                return false;
117            }
118        } else if (!principal.equals(other.principal)) {
119            return false;
120        }
121        return true;
122    }
123}