001/**
002 * Copyright (C) 2014  Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
003 *
004 * This file is part of Dicoogle/dicoogle.
005 *
006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * Dicoogle/dicoogle is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with Dicoogle.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package pt.ua.dicoogle.server.queryretrieve;
020
021
022import aclmanager.core.ACLManagerInterface;
023import aclmanager.core.ACLXMLParser;
024import aclmanager.core.LuceneQueryACLManager;
025import aclmanager.exceptions.CannotParseFileException;
026
027import java.io.File;
028import java.util.concurrent.Executor;
029
030import pt.ua.dicoogle.core.ServerSettings;
031
032import org.dcm4che2.data.UID;
033import org.dcm4che2.net.CommandUtils;
034import org.dcm4che2.net.Device;
035import org.dcm4che2.net.NetworkApplicationEntity;
036import org.dcm4che2.net.NetworkConnection;
037import org.dcm4che2.net.NewThreadExecutor;
038import org.dcm4che2.net.TransferCapability;
039import org.dcm4che2.net.service.VerificationService;
040import org.slf4j.LoggerFactory;
041
042import pt.ua.dicoogle.sdk.Utils.Platform;
043import pt.ua.dicoogle.server.DicomNetwork;
044
045/**
046 *
047 * @author Luís A. Bastião Silva <bastiao@ua.pt>
048 */
049public class QueryRetrieve extends DicomNetwork 
050{
051
052    /**** Class Atributes ****/
053    
054
055    ServerSettings s  = ServerSettings.getInstance();
056
057    /* Implemented SOP Class */
058    private String sopClass = null;
059
060    private EchoReplyService verifService = null;
061
062    /* DEFAULT Implemented module name */
063    private static final String MODULE_NAME = "DICOOGLE-STORAGE";
064    /* Remote Application Entity (client) */
065    private final NetworkApplicationEntity remoteAE = new NetworkApplicationEntity();
066    /* Remote connection associated with remoteAE */
067    private final NetworkConnection remoteConn = new NetworkConnection();
068    /* Module device */
069    private final Device device = new Device(MODULE_NAME);
070    /* Local Application Entity (this server) 'ea' */
071    private final NetworkApplicationEntity localAE = new NetworkApplicationEntity();
072    /* Local connection associated with localAE 'conn' */
073    private final NetworkConnection localConn = new NetworkConnection();
074    /* True if server is allready started */
075    private boolean started = false;
076    /* True if server is allready started as a Windows Service*/
077    private boolean startedAsService = false;
078    /* Response (to clients) delay (in milisec) */
079    private int rspdelay = 0;                                                           
080
081
082    /* Module executor  -  Server thread */
083    private static Executor executor =  new NewThreadExecutor(MODULE_NAME);        
084
085    private String[] transfCap = ServerSettings.getInstance().getTransfCap().split("[|]");
086    private TransferCapability[] tc = new TransferCapability[5];
087
088    private static String[] multiSop = {UID.StudyRootQueryRetrieveInformationModelFIND,
089                                
090                                UID.PatientRootQueryRetrieveInformationModelFIND
091                                };
092
093    private static String[] moveSop = {UID.StudyRootQueryRetrieveInformationModelMOVE,
094    UID.PatientRootQueryRetrieveInformationModelMOVE};
095    
096    private LuceneQueryACLManager luke;
097  
098    public QueryRetrieve()
099    {
100
101        super("DICOOGLE-QUERYRETRIEVE");
102
103        // super(multiSop, executor);
104                this.sopClass = s.getSOPClass();
105
106
107        //DebugManager.getInstance().debug("SOP Class: ");
108        //DebugManager.getInstance().debug(s.getSOPClass());
109
110        for (String s : transfCap)
111        {
112            //DebugManager.getInstance().debug("TransCap : " + s );
113        }
114
115        tc[0] = new TransferCapability(
116                                        UID.StudyRootQueryRetrieveInformationModelFIND,
117                                        this.transfCap,
118                                        TransferCapability.SCP
119                                      );
120        tc[1] = new TransferCapability(
121                                        UID.StudyRootQueryRetrieveInformationModelMOVE,
122                                        this.transfCap,
123                                        TransferCapability.SCP
124                                      );
125
126        tc[2] = new TransferCapability(
127                                UID.PatientRootQueryRetrieveInformationModelFIND,
128                                this.transfCap,
129                                TransferCapability.SCP
130        );
131        tc[3] = new TransferCapability(
132                        UID.PatientRootQueryRetrieveInformationModelMOVE,
133                        this.transfCap,
134                        TransferCapability.SCP
135        );
136        String [] Verification = {UID.ImplicitVRLittleEndian, UID.ExplicitVRLittleEndian, UID.ExplicitVRBigEndian};
137        tc[4] = new TransferCapability(UID.VerificationSOPClass, Verification, TransferCapability.SCP);
138
139        this.verifService = null;
140        /* server */
141        this.started = false;
142        this.startedAsService = false;
143        this.rspdelay = s.getRspDelay();
144        this.localAE.setInstalled(true);
145        this.localAE.setAssociationAcceptor(true);
146        this.localAE.setAssociationInitiator(false);
147        this.localAE.setNetworkConnection(this.localConn );
148        this.localAE.setAETitle(s.getAE());
149        this.localAE.setTransferCapability(tc);
150        this.localAE.setDimseRspTimeout(s.getDIMSERspTimeout());
151        this.localAE.setIdleTimeout(s.getIdleTimeout());
152        this.localAE.setMaxPDULengthReceive(s.getMaxPDULengthReceive()+1000);
153        this.localAE.setMaxPDULengthSend(s.getMaxPDULenghtSend()+1000);
154
155        try {//TODO: HERE IIII XD
156            File xmlFile = new File(Platform.homePath() + ServerSettings.getInstance().getAccessListFileName());
157            
158            if(xmlFile.exists()){
159                ACLManagerInterface manager = ACLXMLParser.parseFromFile(xmlFile);
160                this.luke = new LuceneQueryACLManager(manager);
161            }
162        } catch (CannotParseFileException ex) {
163            LoggerFactory.getLogger(CFindServiceSCP.class).error(ex.getMessage(), ex);
164        }        
165        
166        this.localAE.register(new CMoveServiceSCP(moveSop, executor, luke));
167        this.localAE.register(new CFindServiceSCP(multiSop, executor, luke));
168        this.localAE.register(new VerificationService());
169
170        this.localConn.setPort(s.getWlsPort());
171        this.localConn.setMaxScpAssociations(s.getMaxClientAssoc());
172        this.localConn.setAcceptTimeout(s.getAcceptTimeout());
173        this.localConn.setConnectTimeout(s.getConnectionTimeout());
174
175        this.device.setDescription(s.getDeviceDescription());
176        this.device.setNetworkApplicationEntity(this.localAE);
177        this.device.setNetworkConnection(this.localConn);        
178    }
179
180
181
182    @Override
183    public boolean doStartService() {
184
185
186        if (this.device != null) 
187        {
188            this.verifService = new EchoReplyService();
189            CommandUtils.setIncludeUIDinRSP(true);
190           
191            try {
192                this.device.startListening(QueryRetrieve.executor);
193                this.verifService.start();
194            } catch (Exception ex) {
195            ex.printStackTrace();
196                 //MainWindow.getMw().add2ServerLogln(ex.getMessage(), LOG_MODES.ERROR);
197                 return false;
198            }
199            this.started = true;
200            //DebugManager.getInstance().debug("Starting server " +
201             //       "- cmove server was started right now .. ");
202                this.startedAsService = true;
203            return true;
204        }
205        return false ;
206    }
207
208    @Override
209    public boolean doStopService() {
210        this.device.stopListening();
211        return true ;
212    }
213
214}