001    /***************************************************************************************************
002     *               MODULE DESCRIPTION
003     ****************************************************************************************************
004     *
005     *               NAME:           SpaceSearch.java
006     *               LANGUAGE:       Java2
007     *               DATE:           5.12.2002
008     *               AUTHOR:         Miika Nurminen, Jyväskylän yliopisto
009     *
010    ****************************************************************************************************
011    *               COPYRIGHT (C) KIURU-PROJEKTIRYHMÄ
012    *               Limited rights granted. Please refer to license
013    ****************************************************************************************************
014     
015    ****************************************************************************************************
016    *               UPDATES
017    ****************************************************************************************************
018    *
019    *   5.12.2002 Initial release
020    *   14.1.2003 /mn
021    *    part of functionality generalized to SearchHadler
022    *  23.4.2003 added officialspaces check for non-static queries. /mn
023    *
024    ****************************************************************************************************/
025    package kiurubeans;
026    
027    import kotkabeans.*;
028    import javax.servlet.http.HttpServletRequest;
029    
030    /**
031     * Implement space searching, ordering & filtering
032     *
033     * @author Miika Nurminen
034     */
035    public class SpaceSearch extends SearchHandler {
036    // Attributes
037    
038      /** Adds new space. No action in bean. */
039      public static final int ADD_RECORD=3;
040      /** Deletes selected spaces. clears search field */
041      public static final int DELETE_SPACES=4; 
042    
043     
044      /**
045       * Search string. Value for SQL ordering
046       */
047      private String code = null; 
048      
049      /** 
050       * Selected spaces used for deleting multiple spaces.
051       */ 
052      private String[] selectedSpaces = new String[0]; 
053      
054      /**
055       * Indicates we search only official spaces (eg. spaces that have 
056       * a responsible organisation).
057       */
058      private boolean officialOnly = true;
059      
060      
061    // Constructors
062      
063      /** Constructs a new instance of SpaceSearch. Defines ordeding. */
064      public SpaceSearch() {                   //upper(field) cannot be applied to aliases
065        Field[] s = {new TextField("code"),
066                     new Field("spaceTypeName")};
067        setVisibleFields(s);
068        assignDefaultOrder();
069      }
070    
071    // Access methods
072    
073      /** 
074       * Returns current max state value. Inherited classes may override this
075       * when new states are introduced.
076       *
077       * @return max state value
078       */
079      protected int getMaxState() {
080        return 4;
081      }
082    
083      /**
084       * Getter for attribute selectedSpaces
085       * @return spaces selected by user
086       */
087      public String[] getSelectedSpaces() { return selectedSpaces; }
088      
089      /**
090       * Setter for attribute selectedSpaces
091       * @param s spaces selected by user
092       */  
093      public void setSelectedSpaces(String[] s) { selectedSpaces=s; }
094      
095      /** Sets the <i>i</i>th selected space
096       * @param i Which space is going to be set
097       * @param s The id of the selected space
098       */  
099      public void setSelectedSpaces(int i,String s) { selectedSpaces[i]=s; }
100    
101      /** Returns the <i>i</i>th selected space
102       * @return The id of the selected space
103       * @param i Which space is given
104       */  
105      public String getSelectedSpaces(int i) { return selectedSpaces[i]; }
106    
107      /**
108       * Getter for attribute officialOnly
109       * @return true if only official spaces are retrieved
110       */  
111      public boolean getOfficialOnly() {
112        return this.officialOnly;
113      }
114      
115      /**
116       * Setter for attribute officialOnly
117       * @param b determines if only official spaces are retrieved
118       */  
119      public void setOfficialOnly(boolean b) {
120        this.officialOnly=b;
121      }
122      
123      /** Returns SQL clause for getting only official spaces.
124       * @return " and "+condition for officials or emptystring
125       * @param spacealias space table alias used in sql
126       * @param officialOnly if true, only official spaces are returned
127       */
128      public static String getOfficialSqlClause(String spacealias,boolean officialOnly) {
129        if (KiuruString.isEmpty(spacealias)) throw new IllegalArgumentException("empty spacealias!");
130        if (officialOnly==false) return "";
131        return " and "+spacealias+".organisationid is not null ";
132      }
133      
134      /**
135       * Returns sql clause for getting official spaces. assumes space alias is
136       * s.
137       * @return sql clause for getting official spaces.
138       */
139      private String getOfficialSqlClause() {
140        return getOfficialSqlClause("s", getOfficialOnly());
141      }
142      
143      /**
144       * Getter for attribute code.
145       * @return user's query string
146       */  
147      public String getCode() {
148        if (code==null) return "";
149        return this.code;
150      }
151      
152      /**
153       * Setter for attribute code.
154       * @param code user's query string
155       */  
156      public void setCode(String code) {
157        this.code = KiuruString.sqlTrim(code);//kotkabeans.Encoder.SQLEncode(code).trim();
158      }
159    
160      /**
161       * Sets bean state to DELETE_SPACES. Usually called from a web form.
162       *
163       * @param s any nonempty string.
164       * @see #DELETE_SPACES
165       */  
166      public void setSubmitDelete(String s) {
167        setEnumState(DELETE_SPACES);
168      }
169      
170      /**
171       * Sets bean state to ADD_RECORD. Usually called from a web form.
172       *
173       * @param s any nonempty string.
174       * @see #ADD_RECORD
175       */  
176      public void setSubmitAdd(String s) {
177        setEnumState(ADD_RECORD);
178      }
179    
180    // Operations
181    
182      /** Ensures empty request parameters are clearer when entity is posted.
183       * <p>
184       * If bean is used in a JSP, this should be called in the beginning of page.
185       * If form content is "" or null it is not sent via HTTP, so those fields
186       * must be cleared manually.
187       *
188       * @param request HTTP request with parameters
189       * @see SearchHandler#clearEmptyParameters(HttpServletRequest)
190       */
191      protected void doClearEmptyParameters(HttpServletRequest request) {
192        if ((request.getParameter("code")!=null) && (request.getParameter("code").equals("") && this.code!=null)) {
193          setCode("");
194        }
195        if (KiuruString.isEmpty(request.getParameter("officialOnly"))) {
196          setOfficialOnly(false);
197        }
198      }
199      
200      /**  Returns all spaces (code, spaceid, spacetypename) of a given spacegroup 
201       * @return spaces of a given spacegroup
202       * @param spacegroupid spacegroup where spaces should be located
203       * @throws Exception if problems with db connection
204       */
205      public static RS2 getSpaceGroupSpaces(int spacegroupid) throws Exception {
206        return SimpleDb.simpleQuery("KiuruSpace getspaces","select code,s.spaceid as spaceid,t.name as spacetypename from space as s left outer join spacetype as t on s.spacetypeid=t.spacetypeid, spacegroupspace as sgs "+
207          "where sgs.spaceid = s.spaceid and sgs.deleted=false and sgs.spacegroupid="+Integer.toString(spacegroupid)+" order by code");
208      }
209      
210      /**  Returns all spaces (code, spaceid) of a given spacegroup 
211       * @return spaces of a given spacegroup
212       * @param spacegroupid spacegroup where spaces should be located
213       * @throws Exception if problems with db connection
214       */
215      public static RS2 getPlainSpaceGroupSpaces(int spacegroupid) throws Exception {
216        return SimpleDb.simpleQuery("KiuruSpace getspaces",
217        "select code,s.spaceid as spaceid from space as s, spacegroupspace as sgs "+
218          "where sgs.spaceid = s.spaceid and sgs.deleted=false and sgs.spacegroupid="+Integer.toString(spacegroupid)+" order by code");
219      }
220      
221      /**  Returns all spaceids of a given spacegroup 
222       * @return spaces of a given spacegroup
223       * @param spacegroupid spacegroup where spaces should be located
224       * @throws Exception if problems with db connection
225       */
226      public static RS2 getSpaceGroupSpaceIds(int spacegroupid) throws Exception {
227        return SimpleDb.simpleQuery("KiuruSpace getspaces",
228        "select spaceid from spacegroupspace as sgs "+
229          "where sgs.deleted=false and sgs.spacegroupid="+Integer.toString(spacegroupid));
230      }
231      
232      
233      /**
234       * Returns space codes for spaces with given ids
235       * @param spaceids ids for spaces to be retrieved
236       * @throws Exception if problems with db connection
237       * @return space codes
238       */  
239      public static RS2 getSpaceCodes(String[] spaceids) throws Exception {
240        if ((spaceids==null) || (spaceids.length==0)) return null;
241        StringBuffer sb = new StringBuffer(20);
242        sb.append("select distinct code,spaceid from space as s ");
243        sb.append("where s.deleted=false ");
244        sb.append("and (");
245        sb.append(SimpleDb.formatOrSet("s.spaceid",spaceids));
246        sb.append(") ");
247        sb.append("order by code");
248        return SimpleDb.simpleQuery("KiuruSpace getspacecodes",sb.toString());
249      }
250      
251      /** Returns all spaces of given spacegroups + additional spaces in alphabethical order
252       * if no spacegroupids or spaceids are given, retuns NULL
253       * @param spacegroupids input spacegroupids
254       * @param spaceids inputspaceids
255       * @throws Exception if problems with db connetions
256       * @return spaces in form (code, spaceid, spacetypename)
257       */
258      public static RS2 getSpaceGroupSpaces(String[] spacegroupids,String[] spaceids ) throws Exception {
259        StringBuffer sb = new StringBuffer(20);
260        boolean sg = ((spacegroupids!=null) && (spacegroupids.length>0));
261        boolean sp = ((spaceids!=null) && (spaceids.length>0));
262        
263        sb.append("select distinct code,s.spaceid as spaceid,t.name as spacetypename ");
264        sb.append("from space as s left outer join spacetype as t on s.spacetypeid=t.spacetypeid, spacegroup as sg, spacegroupspace as sgs ");
265        sb.append("where s.deleted=false ");
266        if (sg || sp) {
267          sb.append("and ( ");
268          if (sg) {
269            sb.append(" ( sgs.spaceid = s.spaceid and sgs.deleted=false and sgs.spacegroupid = sg.spacegroupid and sg.deleted=false and ");
270            sb.append(SimpleDb.formatOrSet("sg.spacegroupid", spacegroupids));
271            sb.append(") ");
272          }
273          if (sp) {
274            if (sg) sb.append("or (");
275            sb.append(SimpleDb.formatOrSet("s.spaceid",spaceids));
276            if (sg) sb.append(") ");
277          }
278          sb.append(" ) ");
279        } 
280        else return null;
281        sb.append("order by code");
282        return SimpleDb.simpleQuery("KiuruSpace getspacegroupspaces",sb.toString());
283      }
284      
285      
286      /** Returns all spaces of given spacegroups + additional spaces in alphabethical order
287       * if no spacegroupids or spaceids are given, retuns NULL
288       * @param spacegroupids input spacegroupids
289       * @param spaceids inputspaceids
290       * @throws Exception if problems with db connetions
291       * @return spaces in form (code, spaceid)
292       */
293      public static RS2 getPlainSpaceGroupSpaces(String[] spacegroupids,String[] spaceids ) throws Exception {
294        boolean sg = ((spacegroupids!=null) && (spacegroupids.length>0));
295        boolean sp = ((spaceids!=null) && (spaceids.length>0));
296        if (sg==false) return getSpaceCodes(spaceids);
297        StringBuffer sb = new StringBuffer(20);
298        
299        sb.append("select distinct code,s.spaceid as spaceid ");
300        sb.append("from space as s, spacegroupspace as sgs ");
301        sb.append("where s.deleted=false ");
302        if (sg || sp) {
303          sb.append("and ( ");
304          if (sg) {
305            sb.append(" ( sgs.spaceid = s.spaceid and sgs.deleted=false and ");
306            sb.append(SimpleDb.formatOrSet("sgs.spacegroupid", spacegroupids));
307            sb.append(") ");
308          }
309          if (sp) {
310            if (sg) sb.append("or (");
311            sb.append(SimpleDb.formatOrSet("s.spaceid",spaceids));
312            if (sg) sb.append(") ");
313          }
314          sb.append(" ) ");
315          
316      /*    if (sp) { testing union, too slow...
317            if (sg) sb.append("union select distinct code,s.spaceid as spaceid from space as s where s.deleted=false and (");
318            sb.append(SimpleDb.formatOrSet("s.spaceid",spaceids));
319            if (sg) sb.append(") ");   
320          } */
321      }
322        else return null;
323        sb.append("order by code");
324        return SimpleDb.simpleQuery("KiuruSpace getspacegroupspaces",sb.toString());
325      }
326    
327     
328      /**  Returns all spaces with code match. Note! This might be called automatically
329       * within performaction. Currently must be called manually.
330       * @throws Exception if problems with db connection
331       * @return matched spaces (code,spaceid,spacetypename)
332       */
333      public RS2 getSpaces() throws Exception {
334        if (this.code==null) return null; // getcode clears null away...
335        String t = SimpleDb.formatSearchString("code",getCode(),true);
336        return SimpleDb.simpleQuery("SpaceSearch getspaces","select code,s.spaceid as spaceid,t.name as spacetypename from space as s left outer join spacetype as t on s.spacetypeid=t.spacetypeid "+
337          "where s.deleted=false "+t+getOfficialSqlClause()+
338          getOrderClause());
339      }
340    
341      
342      /** Default implementation of clearing action state. Descendant classes may
343       * override this.
344       * @see SearchHandler#doClearActionState(HttpServletRequest)
345       * @param request The request-object of the JSP.
346       */
347      protected void doClearActionState(HttpServletRequest request) {
348        if ((getEnumState()==KiuruHandler.NO_ACTION) && (this.code!=null)) 
349          setEnumState(SUBMIT_SEARCH); // because of a bug in Mozilla when pressing enter in searchfield.
350        else super.doClearActionState(request);
351      }
352    
353      /**
354       * Performs action based on actionType. Called from performAction.
355       * Descendant classes should override this and call the same method
356       * in inherited class as default.
357       *
358       * @throws Exception If something went wrong during actual executed action.
359       * @see KiuruHandler#performAction()
360       */  
361      protected void defaultAction() throws java.lang.Exception {
362        switch (getEnumState()) {
363          case ADD_RECORD:
364            break;
365          case DELETE_SPACES:
366            deleteSpaces();
367          break;
368          default: // RESET_SEARCH by default
369            super.defaultAction();
370            break;
371        }
372      }
373      
374      /**
375       * Implementation for SUBMIT_SEARCH
376       */
377       public void submitSearch() {
378         if (this.code==null) setCode("");
379       }
380       
381      /**
382       * Implementation for RESET_SEARCH
383       */
384       public void resetSearch() {
385         this.code=null;
386       }
387    
388      
389      /** 
390       * Deletes selected spaces. Use with caution... 
391       * Method uses KiuruSpace's deleteRecord method.
392       *
393       * @see KiuruSpace#deleteRecord()
394       */
395      void deleteSpaces() {
396        if ((getUser()!=null) && (getError()!=null)) {
397          throw new IllegalArgumentException("User and error must be assigned!");
398        }
399        if ((getSelectedSpaces()==null) || (getSelectedSpaces().length==0)) {
400          getError().setError("Poistettavia saleja ei valittu!");    
401          return;
402        }
403        KiuruSpace k = new KiuruSpace(0, getError());
404        k.setUser(getUser());
405        for (int i=0; i<getSelectedSpaces().length; i++) {
406          k.setSpaceId(Integer.parseInt(getSelectedSpaces(i)));
407          k.deleteRecord();
408        }
409      }
410    
411      /** Returns favorite spaces of user with given id, null if not exists.
412       * @return RS2 fields: code, spaceid, spacetypeid
413       * @param userId user whose favorites we are getting
414       * @throws Exception if problems with db connection
415       */
416      public static RS2 getFavoriteSpaces(int userId) throws java.lang.Exception {
417        RS2 rs = SpaceGroupSearch.getFavoriteSpaceGroup(userId);
418        if (rs==null) return null;
419        if (!rs.next()) return null;
420        RS2 rs2 = getSpaceGroupSpaces(rs.getInt("spacegroupid"));
421        return rs2;
422      }
423      
424      /**
425       * Returns user's favorite space ids in a single delimited string, null if not exists
426       * @param userId user whose favorites we are getting
427       * @param delim string delimiter
428       * @throws Exception if problems with db connection
429       * @return space ids in a single delimited string
430       */  
431      public static String getFavoriteSpacesWithDelims(int userId,String delim) throws java.lang.Exception {
432        RS2 rs = getFavoriteSpaces(userId);
433        if (rs==null) return null;
434        StringBuffer result = new StringBuffer(30);
435        while (rs.next()) {
436          if (result.length()>0) result.append(delim);
437          result.append(rs.getString("spaceid"));
438        }
439        return result.toString();
440      }
441    
442      /** Gets code of given space.
443       * @return RS2 containg code of space.
444       * @param spaceId Id of given space.
445       * @throws Exception if problems with db connection
446       */
447      public static RS2 getSpacesCode(int spaceId) throws Exception {
448        RS2 rs = SimpleDb.simpleQuery("SpaceSearch.getSpaceCode db",
449        "SELECT code from space where deleted=false and spaceid=" + spaceId);
450        return rs;
451      }
452      
453     
454    }
455    /***************************************************************************************************
456    *               COPYRIGHT (C) KIURU-PROJEKTIRYHMÄ
457    *               Limited rights granted. Please refer to license
458    ****************************************************************************************************/