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 */ 019/** 020 * Based on a String it will able to separate the strings 021 * and it will be easly extended 022 * 023 * NOTE: 024 * The main proposal of the class is that Search GUI call it 025 * and further for QueryRetrieve Service 026 * 027 */ 028package pt.ua.dicoogle.core; 029 030 031import java.util.ArrayList; 032import java.util.Iterator; 033import java.util.StringTokenizer; 034 035import pt.ua.dicoogle.sdk.utils.TagsStruct; 036 037/** 038 * 039 * @author Luís A. Bastião Silva <bastiao@ua.pt> 040 */ 041public class QueryExpressionBuilder 042{ 043 044 private ArrayList <String> tokens = null ; 045 046 private ArrayList <String> tags = null ; 047 048 049 050 public QueryExpressionBuilder(String text, ArrayList tags) 051 { 052 this(text); 053 this.tags = tags ; 054 } 055 056 057 public QueryExpressionBuilder(String freetext) 058 { 059 060 setTokens(new ArrayList<String>()); 061 062 freetext = freetext.replace("^", " "); 063 064 StringTokenizer st = new StringTokenizer(freetext); 065 066 /** XXX probably it can be improved, there're some strange charsets 067 * put it up set 068 */ 069 070 while (st.hasMoreTokens()) 071 { 072 String ss = st.nextToken(); 073 if (ss.contains("^")) 074 { 075 for (String newToken : ss.split("^")) 076 tokens.add(newToken); 077 078 } 079 else 080 tokens.add(ss); 081 } 082 083 084 /** 085 * Get tags ; 086 * it it allocated in Run Time, so I have instance access to 087 * singletone 088 */ 089 090 TagsStruct _tags = TagsStruct.getInstance(); 091 092 this.tags = _tags.getDIMAlias(); 093 094 } 095 096 /** 097 * @return the tokens 098 */ 099 public ArrayList<String> getTokens() 100 { 101 return tokens; 102 } 103 104 /** 105 * @param tokens the tokens to set 106 */ 107 public void setTokens(ArrayList<String> tokens) 108 { 109 this.tokens = tokens; 110 } 111 112 113 public String getQueryString() 114 { 115 /** It will be used to call the Lucene - Indexer 116 * It crucial respect the BNF grammer able to search in library 117 */ 118 String queryString = "" ; 119 120 121 /** Search in Lucene in freetext is non-Trivial 122 * There are some constrains by the library Lunce 2.X 123 * it was implemented with the repeat of fields 124 * 125 * Get it for free text: "Smith CT", where the tags domain is: 126 * PatientName and Modality 127 * 128 * the result should be: 129 * 130 * (PatientName=Smith OR Modality=Smith) OR 131 * (PatientName=CT OR Modality=CT) 132 * 133 * More general expression was: 134 * (field1=a1 or field2=a1 or field3=a3 .. or fieldn=an) or 135 * (...) 136 * (field1=z1 or field2=z2 or field3=z3 .. or fiendn=zn) 137 * 138 * This way the search will be in free text really 139 * 140 */ 141 142 Iterator<String> itTokens = tokens.iterator(); 143 Iterator<String> itTags; 144 145 String token = null ; 146 147 /** Build the query string 148 * 149 * Iterating for each token 150 */ 151 while(itTokens.hasNext()) 152 { 153 /** 154 * Iterating each tags 155 */ 156 queryString += "("; 157 String tag = null ; 158 159 token = itTokens.next(); 160 itTags = tags.iterator(); 161 while (itTags.hasNext()) 162 { 163 164 tag = itTags.next(); 165 queryString += tag+":"+token ; 166 /** 167 * If it have next then the logical condition will continue 168 * in next iteration 169 */ 170 if (itTags.hasNext()) 171 { 172 queryString += " OR "; 173 } 174 } 175 queryString += "OR others:" + token + " )"; 176 177 if (itTokens.hasNext()) 178 { 179 queryString += " AND "; 180 } 181 182 } 183 184 return queryString; 185 } 186 187 /** 188 * @return the tags 189 */ 190 public ArrayList<String> getTags() 191 { 192 return tags; 193 } 194 195 /** 196 * @param tags the tags to set 197 */ 198 public void setTags(ArrayList<String> tags) 199 { 200 this.tags = tags; 201 } 202 203}