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
021import java.text.Format;
022import java.text.SimpleDateFormat;
023import java.util.Date;
024import java.util.HashMap;
025
026import pt.ua.dicoogle.core.exceptions.CFindNotSupportedException;
027
028import java.util.Iterator;
029import java.util.Set;
030
031import org.dcm4che2.data.DicomElement;
032import org.dcm4che2.data.DicomObject;
033import org.dcm4che2.data.Tag;
034
035import pt.ua.dicoogle.core.ServerSettings;
036import pt.ua.dicoogle.sdk.utils.TagValue;
037import pt.ua.dicoogle.sdk.utils.TagsStruct;
038
039/**
040 *
041 *  [SOP Class name] -  [SOP Class UID]
042 *   Patient Root Q/R Find - 1.2.840.10008.5.1.4.1.2.1.1
043 *   Study Root Q/R Find - 1.2.840.10008.5.1.4.1.2.2.1
044 *   NOT SUPPORTED: @depracated
045 *   Patient-Study Root Q/R Find (Retired) - 1.2.840.10008.5.1.4.1.2.3.1
046 *
047 *
048 *
049 * @author Luís A. Bastião Silva <bastiao@ua.pt>
050 */
051public class CFindBuilder
052{
053
054    private boolean patientRoot = false ;
055    private boolean studyRoot = false ;
056
057    private String query = "";
058    
059
060    public CFindBuilder(DicomObject key, DicomObject rsp) throws CFindNotSupportedException
061    {
062
063        //if (!setRoot(rsp))
064        //    throw new CFindNotSupportedException() ;
065
066              
067        /**
068         * Sample output
069        (0008,0005) CS #10 [ISO_IR 100] Specific Character Set
070        (0008,0020) DA #18 [20090531-20090531] Study Date
071        (0008,0030) TM #22 [000000.000-120000.000] Study Time
072        (0008,0050) SH #0 [] Accession Number
073        (0008,0052) CS #6 [STUDY] Query/Retrieve Level
074        (0008,0061) CS #2 [XA] Modalities in Study
075        (0008,1030) LO #0 [] Study Description
076        (0010,0010) PN #0 [] Patient's Name
077        (0010,0020) LO #0 [] Patient ID
078        (0010,0030) DA #0 [] Patient's Birth Date
079        (0020,000D) UI #0 [] Study Instance UID
080        (0020,0010) SH #0 [] Study ID
081        (0020,1208) IS #0 [] Number of Study Related Instances
082         */
083
084        /** Search by required fields
085
086         *
087         *
088        */
089
090        // Get Affected SOP Classs UID
091        DicomElement elem = rsp.get(Integer.parseInt("00000002", 16));
092        String affectedSOP = new String(elem.getBytes());
093
094        TagsStruct tagstruct = TagsStruct.getInstance();
095        
096        //TagsStruct.getInstance().toStringNew();
097        boolean all=false ;
098        String append = "" ;
099        query="";
100        System.out.println(tagstruct.getDIMFields().size());
101        Iterator<TagValue> it = tagstruct.getDIMFields().iterator();
102        while(it.hasNext())
103        {
104            /** Verify if this tags exists
105            */
106                TagValue tag = it.next();
107            int k = tag.getTagNumber() ;
108            DicomElement e = key.get(k);
109            //DebugManager.getInstance().debug("get key::"+ k );
110            if (e!=null)
111            {
112                String value = new String(e.getBytes());
113                //DebugManager.getInstance().debug("Value getted in CFIND RP:<"+t.get(k).getAlias() + "> "+ value  +".");
114                if (value.equals(""))
115                {
116                    continue ;
117
118                }
119                else
120                {
121                    value=value.trim();
122                    boolean modified = false ;
123                    // TODO :: Study Date need to be rewritted
124                    // and others weird tags like // should be mapped to lucene!
125                    if (k == Tag.ModalitiesInStudy)
126                    {
127                        String [] modality = value.split("\\\\");
128                        int i = 0 ;
129                        String modalityQuery = "";
130                        for (String mod : modality )
131                        {
132
133                            //DebugManager.getInstance().debug(mod);
134
135                            if (modified)
136                            {
137                                // There is already exist a modality
138                                modalityQuery += " OR ";
139                            }
140
141                            i++ ; 
142                            modified = true ;
143                            modalityQuery += "Modality" + ":" + mod;
144                        }
145                        if (!modalityQuery.equals(""))
146                        {
147                            System.err.println(modalityQuery);
148                            query = query + append +  " (" + modalityQuery + ")" ;
149                        }
150                        
151                    }
152
153                    else if(k == Tag.StudyDate)
154                    {
155                        System.out.println("Value :@" +value+".");
156                        
157                        String [] date = value.split("-");
158                        int i = 0 ;
159                        if (date.length==1)
160                        {
161                            
162                            if (!value.contains("-"))
163                            {
164                                query = query + append +tag.getAlias() + ":[" + date[0] + " TO " +
165                                date[0] + "]" ;
166                            }
167                            else
168                            {
169                                
170                                 String s;
171                                 Format formatter;
172                                 Date date2 = new Date();
173
174                                 // 01/09/02
175                                 formatter = new SimpleDateFormat("YYYYMMdd");
176                                 s = formatter.format(date2);
177
178                                 query = query + append +tag.getAlias() + ":[" + date[0] + " TO " +
179                                 s + "]" ;
180                            }
181                            
182                            
183                            //query = query +append + t.get(k).getAlias() + ":[" + date[0] + " TO " +
184                            //    date[0] + "]" ;
185                        }
186                        else if(date.length==2)
187                        {
188                            query = query + append + tag.getAlias() + ":[" + date[0] + " TO " +
189                                date[1] + "]" ;
190                        }
191                        modified = true ;
192                    }
193                    
194                    
195                    else if(k == Tag.StudyTime)
196                    {
197                        String [] date = value.split("-");
198                        int i = 0 ;
199                        if (date.length==1)
200                        {
201                            query = query + append +tag.getAlias() + ":[" + date[0] + " TO " +
202                                date[0] + "]" ;
203                            /*if (!value.contains("-"))
204                            {
205                                query = query + append +t.get(k).getAlias() + ":[" + date[0] + " TO " +
206                                date[0] + "]" ;
207                            }
208                            else
209                            {
210                                
211                                 String s;
212                                 Format formatter;
213                                 Date date2 = new Date();
214
215                                 // 01/09/02
216                                 formatter = new SimpleDateFormat("YYYYMMdd");
217                                 s = formatter.format(date2);
218
219                                 query = query + append +t.get(k).getAlias() + ":[" + date[0] + " TO " +
220                                 s + "]" ;
221                            }*/
222                        }
223                        else if(date.length==2)
224                        {
225                            query = query + append + tag.getAlias() + ":[" + date[0] + " TO " +
226                                date[1] + "]" ;
227                        }
228                        modified = true ;
229                    }
230                    
231                    
232
233                    else
234                    {
235                        modified = true ; 
236                        query += append + tag.getAlias() + ":" + value;
237                    }
238
239                    if (modified && it.hasNext())
240                    {
241                        append = " AND ";
242                    }
243
244                }
245
246            }
247        }
248        
249        if (query.equals(""))
250            query="*:*"; 
251        //DebugManager.getInstance().debug(">> Query String DICOM: "+ query);
252
253
254    }
255
256    public String getQueryString()
257            {
258        return this.query;
259    }
260
261    private synchronized  boolean setRoot(DicomObject rsp)
262    {
263        /**
264         * Verify if it is inside of:
265         * Affected SOP Class UID (0000,0002)
266         * Checked in C-FIND RQ in DICOM
267         * It is one of three ([P|S|PS] Root )
268         */
269
270        DicomElement elem = rsp.get(Integer.parseInt("00000002", 16));
271        String affectedSOP = new String(elem.getBytes());
272
273
274
275        //DebugManager.getInstance().debug(">" + affectedSOP);
276        //DebugManager.getInstance().debug(">> "+ServerSettings.getInstance().getSOPClass());
277        
278
279
280        boolean found = false;
281
282        for (String i : ServerSettings.getInstance().getSOPClass().split("\\|"))
283        {
284            //DebugManager.getInstance().debug("It have in settings:>: " + i);
285
286            if (affectedSOP.equals(i))
287            {
288                /**
289                1.2.840.10008.5.1.4.1.2.1.1 (Patient)
290                1.2.840.10008.5.1.4.1.2.2.1 (Study)
291                 */
292                //DebugManager.getInstance().debug(">>> Affected SOPs in ");
293                if (affectedSOP.equals("1.2.840.10008.5.1.4.1.2.1.1"))
294                {
295                    this.patientRoot = true ;
296                    found = true ;
297                }
298                else if (affectedSOP.equals("1.2.840.10008.5.1.4.1.2.2.1"))
299                {
300                    this.studyRoot = true ;
301                    found = true  ;
302                }
303                break ;
304            }
305        }
306
307        return found ;
308
309    }
310
311
312
313    /**
314     * @return the patientRoot
315     */
316    public boolean isPatientRoot()
317    {
318        return patientRoot;
319    }
320
321    /**
322     * @param patientRoot the patientRoot to set
323     */
324    public void setPatientRoot(boolean patientRoot)
325    {
326        this.patientRoot = patientRoot;
327    }
328
329    /**
330     * @return the studyRoot
331     */
332    public boolean isStudyRoot()
333    {
334        return studyRoot;
335    }
336
337    /**
338     * @param studyRoot the studyRoot to set
339     */
340    public void setStudyRoot(boolean studyRoot)
341    {
342        this.studyRoot = studyRoot;
343    }
344
345    /**
346     * @return the query
347     */
348    public String getQuery()
349    {
350        return query;
351    }
352
353    /**
354     * @param query the query to set
355     */
356    public void setQuery(String query)
357    {
358        this.query = query;
359    }
360
361
362    public static boolean isPatientRoot(DicomObject rsp)
363    {
364        DicomElement elem = rsp.get(Integer.parseInt("00000002", 16));
365        String affectedSOP = new String(elem.getBytes());
366
367        if (affectedSOP.equals("1.2.840.10008.5.1.4.1.2.2.1"))
368        {
369            return true;
370        }
371        return false;
372    }
373
374    public static boolean isStudyRoot(DicomObject rsp)
375    {
376        DicomElement elem = rsp.get(Integer.parseInt("00000002", 16));
377        String affectedSOP = new String(elem.getBytes());
378        if (affectedSOP.equals("1.2.840.10008.5.1.4.1.2.1.1"))
379        {
380            return true;
381        }
382        return false;
383    }
384    
385
386}