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) 2011
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.tool.qidors.test;
040
041import static org.junit.Assert.assertTrue;
042
043import java.io.IOException;
044import java.security.GeneralSecurityException;
045
046import org.dcm4che3.data.Attributes;
047import org.dcm4che3.data.ElementDictionary;
048import org.dcm4che3.data.VR;
049import org.dcm4che3.net.IncompatibleConnectionException;
050import org.dcm4che3.tool.common.test.TestResult;
051import org.dcm4che3.tool.common.test.TestTool;
052import org.dcm4che3.tool.qidors.QidoRS;
053
054
055/**
056 * @author Hesham elbadawi <bsdreko@gmail.com>
057 */
058public class QidoRSTool implements TestTool {
059
060
061    public enum QidoMetaDataType {
062        JSON, XML;
063    }
064    private TestResult result;
065    private final String url;
066    private Attributes queryAttrs;
067    private Attributes returnAttrs;
068    private final boolean fuzzy;
069    private final boolean timezoneAdjustment;
070    private final String limit;
071    private int expectedMatches = Integer.MIN_VALUE; // negative value means to not check
072    private final boolean returnAll;
073    private int numMatches;
074    private final String offset;
075
076    public QidoRSTool(String url, String limit, boolean fuzzy, boolean timezone, boolean returnAll, String offset) {
077        super();
078        this.offset = offset;
079        this.url = url;
080        this.limit = limit;
081        this.fuzzy = fuzzy;
082        this.timezoneAdjustment = timezone;
083        this.returnAll = returnAll;
084    }
085
086    public void queryJSON(String testDescription) throws IOException,
087            InterruptedException, IncompatibleConnectionException,
088            GeneralSecurityException {
089        query(testDescription, "JSON");
090    }
091
092    public void queryXML(String testDescription) throws IOException,
093            InterruptedException, IncompatibleConnectionException,
094            GeneralSecurityException {
095        query(testDescription, "XML");
096    }
097
098    private void query(String testDescription, String mediaType) throws IOException {
099        QidoRS qidors = new QidoRS(this.isFuzzy(), this.isTimezoneAdjustment(), this.isReturnAll(), this.getLimit(), this.getOffset(), this.getQueryAttrs(), this.getReturnAttrs(), mediaType, this.getUrl());
100        qidors.setRunningModeTest(true);
101        long t1 = System.currentTimeMillis();
102        QidoRS.qido(qidors, false);
103        long t2 = System.currentTimeMillis();
104        numMatches = qidors.getNumMatches();
105        validateMatches(testDescription);
106        init(new QidoRSResult(testDescription, expectedMatches, numMatches, t2 - t1, qidors.getTimeFirst() - t1, qidors.getResponseAttrs()));
107    }
108
109    private void validateMatches(String testDescription) {
110        if (this.expectedMatches >= 0)
111            assertTrue("test[" + testDescription
112                    + "] not returned expected result:" + this.expectedMatches
113                    + " but:" + numMatches, numMatches == this.expectedMatches);
114    }
115
116    /**
117     * Add a field and value that should be queried for ("attributeID=value").
118     * 
119     * @param tag
120     * @param value
121     */
122    public void addQueryTag(int tag, String value) {
123        VR vr = ElementDictionary.vrOf(tag, null);
124        Attributes attr = this.getQueryAttrs()!=null?this.getQueryAttrs():new Attributes();
125        attr.setString(tag, vr, value);
126        this.setQueryAttrs(attr);
127    }
128
129    public void clearQueryKeys() {
130        this.queryAttrs = new Attributes();
131    }
132    public void addAll(Attributes attrs) {
133        queryAttrs.addAll(attrs);
134    }
135
136    /**
137     * Add a field that should be included with the responses
138     * ("includefield=attributeID").
139     * 
140     * <p>
141     * If returnAll (QidoRSParameters.returnAll) is set to true, then this will
142     * be ignored (and "includefield=all" will be set instead).
143     * 
144     * <p>
145     * E.g. <code>addReturnTag(Tag.StudyDescription)</code>
146     * 
147     * @param tag
148     */
149    public void addReturnTag(int tag) {
150        VR vr = ElementDictionary.vrOf(tag, null);
151        Attributes attr = this.getReturnAttrs()!=null?this.getReturnAttrs():new Attributes();
152        attr.setNull(tag,vr);
153        this.setReturnAttrs(attr);
154    }
155
156    /**
157     * If this is set to a non-negative number validation step of the returned
158     * matches will be performed.
159     * 
160     * @param matches
161     */
162    public void setExpectedMatches(int matches) {
163        this.expectedMatches = matches;
164    }
165
166    @Override
167    public void init(TestResult resultIn) {
168        this.result = resultIn;
169    }
170
171    @Override
172    public TestResult getResult() {
173        return this.result;
174    }
175
176    public String getUrl() {
177        return url;
178    }
179
180    public Attributes getQueryAttrs() {
181        return queryAttrs;
182    }
183
184    public void setQueryAttrs(Attributes queryAttrs) {
185        this.queryAttrs = queryAttrs;
186    }
187
188    public boolean isFuzzy() {
189        return fuzzy;
190    }
191
192    public boolean isTimezoneAdjustment() {
193        return timezoneAdjustment;
194    }
195
196    public String getLimit() {
197        return limit;
198    }
199
200    public int getExpectedMatches() {
201        return expectedMatches;
202    }
203
204    public boolean isReturnAll() {
205        return returnAll;
206    }
207
208    public String getOffset() {
209        return offset;
210    }
211
212    public Attributes getReturnAttrs() {
213        return returnAttrs;
214    }
215
216    public void setReturnAttrs(Attributes returnAttrs) {
217        this.returnAttrs = returnAttrs;
218    }
219}