001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in
015 * Java(TM), hosted at https://github.com/gunterze/dcm4che.
016 *
017 * The Initial Developer of the Original Code is
018 * Agfa Healthcare.
019 * Portions created by the Initial Developer are Copyright (C) 2012
020 * the Initial Developer. All Rights Reserved.
021 *
022 * Contributor(s):
023 * See @authors listed below
024 *
025 * Alternatively, the contents of this file may be used under the terms of
026 * either the GNU General Public License Version 2 or later (the "GPL"), or
027 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
028 * in which case the provisions of the GPL or the LGPL are applicable instead
029 * of those above. If you wish to allow use of your version of this file only
030 * under the terms of either the GPL or the LGPL, and not to allow others to
031 * use your version of this file under the terms of the MPL, indicate your
032 * decision by deleting the provisions above and replace them with the notice
033 * and other provisions required by the GPL or the LGPL. If you do not delete
034 * the provisions above, a recipient may use your version of this file under
035 * the terms of any one of the MPL, the GPL or the LGPL.
036 *
037 * ***** END LICENSE BLOCK ***** */
038
039package org.dcm4che3.data;
040
041import java.io.Serializable;
042
043import org.dcm4che3.util.StringUtils;
044
045/**
046 * @author Gunter Zeilinger <gunterze@gmail.com>
047 */
048public class Issuer implements Serializable {
049
050    private static final long serialVersionUID = 5350502680059507981L;
051
052    private String localNamespaceEntityID;
053    private String universalEntityID;
054    private String universalEntityIDType;
055
056    public Issuer(String localNamespaceEntityID, String universalEntityID,
057            String universalEntityIDType) {
058        this.localNamespaceEntityID = localNamespaceEntityID;
059        this.universalEntityID = universalEntityID;
060        this.universalEntityIDType = universalEntityIDType;
061        validate();
062    }
063
064    public Issuer(String s) {
065        this(s, '&');
066    }
067
068    public Issuer(String s, char delim) {
069        String[] ss = StringUtils.split(s, delim);
070        if (ss.length > 3)
071            throw new IllegalArgumentException(s);
072        this.localNamespaceEntityID = emptyToNull(ss[0]);
073        this.universalEntityID = ss.length > 1 ? emptyToNull(ss[1]) : null;
074        this.universalEntityIDType = ss.length > 2 ? emptyToNull(ss[2]) : null;
075        validate();
076    }
077
078    public Issuer(String issuerOfPatientID, Attributes qualifiers) {
079        this(issuerOfPatientID,
080             qualifiers != null ? qualifiers.getString(Tag.UniversalEntityID) : null,
081             qualifiers != null ? qualifiers.getString(Tag.UniversalEntityIDType) : null);
082    }
083
084    public Issuer(Attributes issuerItem) {
085        this(issuerItem.getString(Tag.LocalNamespaceEntityID),
086             issuerItem.getString(Tag.UniversalEntityID),
087             issuerItem.getString(Tag.UniversalEntityIDType));
088    }
089
090    public Issuer(Issuer other) {
091        this(other.getLocalNamespaceEntityID(),
092             other.getUniversalEntityID(),
093             other.getUniversalEntityIDType());
094    }
095
096    protected Issuer() {} // needed for JPA
097
098    public static Issuer fromIssuerOfPatientID(Attributes attrs) {
099        String issuerOfPatientID = attrs.getString(Tag.IssuerOfPatientID);
100        Attributes qualifiers = attrs.getNestedDataset(Tag.IssuerOfPatientIDQualifiersSequence);
101        if (issuerOfPatientID == null
102                && (qualifiers == null
103                    || qualifiers.isEmpty()
104                    || qualifiers.getString(Tag.UniversalEntityID) == null
105                    || qualifiers.getString(Tag.UniversalEntityIDType) == null))
106            return null;
107
108        return new Issuer(issuerOfPatientID, qualifiers);
109    }
110
111    public static Issuer valueOf(Attributes issuerItem) {
112        if (issuerItem == null || issuerItem.isEmpty())
113            return null;
114
115        return new Issuer(issuerItem);
116    }
117
118    private void validate() {
119        if (localNamespaceEntityID == null && universalEntityID == null)
120            throw new IllegalArgumentException(
121                    "Missing Local Namespace Entity ID or Universal Entity ID");
122        if (universalEntityID != null) {
123            if (universalEntityIDType == null)
124                throw new IllegalArgumentException("Missing Universal Entity ID Type");
125        }
126    }
127
128    private String emptyToNull(String s) {
129        return s.isEmpty() ? null : s;
130    }
131
132    public String getLocalNamespaceEntityID() {
133        return localNamespaceEntityID;
134    }
135
136    public String getUniversalEntityID() {
137        return universalEntityID;
138    }
139
140    public String getUniversalEntityIDType() {
141        return universalEntityIDType;
142    }
143
144    public boolean merge(Issuer other) {
145        if (!matches(other))
146            throw new IllegalArgumentException("other=" + other);
147
148        boolean mergeLocalNamespace;
149        boolean mergeUniversal;
150        if (mergeLocalNamespace = this.localNamespaceEntityID == null
151                && other.localNamespaceEntityID != null) {
152            this.localNamespaceEntityID = other.localNamespaceEntityID;
153         }
154        if (mergeUniversal = this.universalEntityID == null
155                && other.universalEntityID != null) {
156            this.universalEntityID = other.universalEntityID;
157            this.universalEntityIDType = other.universalEntityIDType;
158        }
159        return mergeLocalNamespace || mergeUniversal;
160    }
161
162    @Override
163    public int hashCode() {
164        return 37 * (
165                37 * hashCode(localNamespaceEntityID)
166                   + hashCode(universalEntityID))
167                + hashCode(universalEntityIDType);
168    }
169
170    private int hashCode(String s) {
171        return s == null ? 0 : s.hashCode();
172    }
173
174    @Override
175    public boolean equals(Object o) {
176        if (o == this)
177            return true;
178        if (!(o instanceof Issuer))
179            return false;
180        Issuer other = (Issuer) o;
181        return equals(localNamespaceEntityID, other.localNamespaceEntityID)
182                && equals(universalEntityID, other.universalEntityID)
183                && equals(universalEntityIDType, other.universalEntityIDType);
184    }
185
186    private boolean equals(String s1, String s2) {
187        return s1 == s2 || s1 != null && s1.equals(s2);
188    }
189
190    public boolean matches(Issuer other) {
191        if (this == other || other == null)
192            return true;
193
194        boolean matchLocal = localNamespaceEntityID != null
195                && other.localNamespaceEntityID != null;
196        boolean matchUniversal = universalEntityID != null
197                && other.universalEntityID != null;
198
199        return (matchLocal || matchUniversal)
200            && (!matchLocal
201                || localNamespaceEntityID.equals(other.localNamespaceEntityID))
202            && (!matchUniversal
203                || universalEntityID.equals(other.universalEntityID)
204                && universalEntityIDType.equals(other.universalEntityIDType));
205    }
206
207    @Override
208    public String toString() {
209        return toString('&');
210    }
211
212    public String toString(char delim) {
213        if (universalEntityID == null)
214            return localNamespaceEntityID;
215        StringBuilder sb = new StringBuilder();
216        if (localNamespaceEntityID != null)
217            sb.append(localNamespaceEntityID);
218        sb.append(delim);
219        sb.append(universalEntityID);
220        sb.append(delim);
221        sb.append(universalEntityIDType);
222        return sb.toString();
223    }
224
225    public Attributes toItem() {
226        int size = 0;
227        if (localNamespaceEntityID != null)
228            size++;
229        if (universalEntityID != null)
230            size++;
231        if (universalEntityIDType != null)
232            size++;
233
234        Attributes item = new Attributes(size);
235        if (localNamespaceEntityID != null)
236            item.setString(Tag.LocalNamespaceEntityID, VR.UT, localNamespaceEntityID);
237        if (universalEntityID != null)
238            item.setString(Tag.UniversalEntityID, VR.UT, universalEntityID);
239        if (universalEntityIDType != null)
240            item.setString(Tag.UniversalEntityIDType, VR.CS, universalEntityIDType);
241        return item ;
242    }
243
244    public Attributes toIssuerOfPatientID(Attributes attrs) {
245        if (attrs == null)
246            attrs = new Attributes(2);
247        if (localNamespaceEntityID != null)
248            attrs.setString(Tag.IssuerOfPatientID, VR.LO, localNamespaceEntityID);
249        if (universalEntityID != null) {
250            Attributes item = new Attributes(2);
251            item.setString(Tag.UniversalEntityID, VR.UT, universalEntityID);
252            item.setString(Tag.UniversalEntityIDType, VR.CS, universalEntityIDType);
253            attrs.newSequence(Tag.IssuerOfPatientIDQualifiersSequence, 1).add(item);
254        }
255        return attrs;
256    }
257
258}