Mir goes GPL
[mir.git] / source / mircoders / storage / DatabaseContentToTopics.java
1 /*
2  * Copyright (C) 2001, 2002  The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package mircoders.storage;
33
34 import java.lang.*;
35 import java.sql.*;
36 import java.io.*;
37 import java.util.*;
38
39 import freemarker.template.*;
40
41 import mir.storage.*;
42 import mir.entity.*;
43 import mir.misc.*;
44
45 import mircoders.entity.*;
46
47 /**
48  * <b>This class implements the 1-n-relation between
49  * content and topic
50  *
51  */
52
53 public class DatabaseContentToTopics extends Database implements StorageObject{
54
55   private static DatabaseContentToTopics instance;
56
57   // the following *has* to be sychronized cause this static method
58   // could get preemted and we could end up with 2 instances of DatabaseFoo.
59   // see the "Singletons with needles and thread" article at JavaWorld -mh
60   public synchronized static DatabaseContentToTopics getInstance()
61     throws StorageObjectException {
62     if (instance == null) {
63       instance = new DatabaseContentToTopics();
64       instance.myselfDatabase = instance;
65     }
66     return instance;
67   }
68
69   private DatabaseContentToTopics()
70     throws StorageObjectException {
71
72     super();
73     this.hasTimestamp = false;
74     this.theTable="content_x_topic";
75     try { this.theEntityClass = Class.forName("mir.entity.GenericEntity"); }
76     catch (Exception e) { throw new StorageObjectException(e.toString()); }
77
78   }
79
80   /**
81    * This class return an EntityList of Topics
82    * @param EntityContent content
83    * @returns EntityList
84    */
85   public EntityList getTopics(EntityContent content) {
86     EntityList returnList=null;
87     if (content != null) {
88       // get all to_topic from content_x_topic
89       String id = content.getId();
90       String subselect = "id in (select topic_id from " + theTable + " where content_id=" + id+")";
91
92       try {
93         returnList = DatabaseTopics.getInstance().selectByWhereClause(subselect,-1);
94       } catch (Exception e) {
95         theLog.printDebugInfo("-- get topics failed " + e.toString());
96       }
97     }
98     return returnList;
99   }
100
101   /**
102    * Returns a ArrayList of Integer-Objects from a content-id.
103    * @returns ArrayList
104    */
105   public ArrayList getTopicsOfContent(String contentId)
106     throws StorageObjectException {
107     ArrayList returnList = new ArrayList();
108     if (contentId != null) {
109       String sql = "select topic_id from " + theTable + " where content_id=" + contentId;
110       Connection con=null;Statement stmt=null;
111       try {
112         con = getPooledCon();
113         // should be a preparedStatement because is faster
114         stmt = con.createStatement();
115         ResultSet rs = executeSql(stmt,sql);
116         if(rs!=null){
117           while(rs.next()){
118             returnList.add(new Integer(rs.getInt("topic_id")));
119           }
120         }
121       } catch (Exception e) {
122         theLog.printError(e.toString());
123         theLog.printError("-- get topicsofcontent failed");
124       } finally {
125         freeConnection(con,stmt);
126       }
127     }
128     return returnList;
129   }
130
131   /**
132    * Set new topics
133    */
134   public void setTopics(String contentId, String[] topicId)
135     throws StorageObjectException {
136     if (contentId == null){
137       return;
138     }
139     if (topicId==null || topicId[0]==null) {
140       return;
141     }
142     //first check which topics this article has
143     Collection hasTopics = getTopicsOfContent(contentId);
144     Collection toSet = new ArrayList();
145     Collection toDelete = new ArrayList();
146
147     if(hasTopics!=null && hasTopics.size()>0){
148       //now we check if there are new topics and copy them to an array.
149       for(int i = 0; i< topicId.length;i++){
150         boolean set=false;
151         int whichTopic = 0;
152         for(Iterator it=hasTopics.iterator();it.hasNext();){
153           Integer topic = (Integer)it.next();
154           if(topicId[i].equals(topic.toString())){
155             set=true;
156           } else {
157             whichTopic = i;
158           }
159         }
160         if(set==false){
161           toSet.add(topicId[i]);
162           theLog.printDebugInfo("to set: "+ topicId[i]);
163         }
164       }
165       //now we check if we have to delete topics
166       for(Iterator it=hasTopics.iterator();it.hasNext();){
167         boolean delete=true;
168         int whichTopic = 0;
169         Integer topic = (Integer)it.next();
170         for(int i = 0; i< topicId.length;i++){
171           if(topicId[i].equals(topic.toString())){
172             delete=false;
173           } else {
174             whichTopic = i;
175           }
176         }
177         if(delete==true){
178           toDelete.add(topic.toString());
179           theLog.printDebugInfo("to delete: "+ topic.toString());
180         }
181       }
182     } else {
183       //all the topics has to be set, so we copy all to the array
184                         for (int i = 0; i < topicId.length; i++){
185                                 toSet.add(topicId[i]);
186                         }
187     }
188
189     //first delete all row with content_id=contentId
190     String sql = "delete from "+ theTable +" where content_id=" + contentId
191                 + " and topic_id in (";
192     boolean first=false;
193     for(Iterator it = toDelete.iterator(); it.hasNext();){
194       if(first==false){
195         first=true;
196       } else {
197         sql+=",";
198       }
199       sql+= (String)it.next();
200     }
201     sql+=")";
202     Connection con=null;Statement stmt=null;
203     try {
204       con = getPooledCon();
205       // should be a preparedStatement because is faster
206       stmt = con.createStatement();
207       int rs = executeUpdate(stmt,sql);
208     } catch (Exception e) {
209       theLog.printDebugInfo("-- deleting topics failed");
210     } finally {
211       freeConnection(con,stmt);
212     }
213
214     //now insert
215     //first delete all row with content_id=contentId
216     for (Iterator it = toSet.iterator(); it.hasNext();) {
217       sql = "insert into "+ theTable +" (content_id,topic_id) values ("
218             + contentId + "," + (String)it.next() + ")";
219       try {
220         con = getPooledCon();
221         // should be a preparedStatement because is faster
222         stmt = con.createStatement();
223         int rs = executeUpdate(stmt,sql);
224       } catch (Exception e) {
225         theLog.printDebugInfo("-- set topics failed -- insert laenge topicId" + topicId.length);
226       } finally {
227         freeConnection(con,stmt);
228       }
229     }
230   }
231
232   public void deleteByContentId(String contentId)
233     throws StorageObjectException {
234     if (contentId == null) {
235       //theLog.printDebugInfo("-- delete topics failed -- no content id");
236       return;
237     }
238     //delete all row with content_id=contentId
239     String sql = "delete from "+ theTable +" where content_id=" + contentId;
240
241     Connection con=null;Statement stmt=null;
242     try {
243       con = getPooledCon();
244       // should be a preparedStatement because is faster
245       stmt = con.createStatement();
246       ResultSet rs = executeSql(stmt,sql);
247     } catch (Exception e) {
248       //theLog.printDebugInfo("-- delete topics failed  ");
249     } finally {
250       freeConnection(con,stmt);
251     }
252   }
253
254   public void deleteByTopicId(String topicId)
255     throws StorageObjectException {
256     if (topicId == null) {
257       //theLog.printDebugInfo("-- delete topics failed -- no topic id");
258       return;
259     }
260     //delete all row with content_id=contentId
261     String sql = "delete from "+ theTable +" where topic_id=" + topicId;
262
263     Connection con=null;Statement stmt=null;
264     try {
265       con = getPooledCon();
266       // should be a preparedStatement because is faster
267       stmt = con.createStatement();
268       ResultSet rs = executeSql(stmt,sql);
269     } catch (Exception e) {
270       theLog.printDebugInfo("-- delete topics failed ");
271     } finally {
272       freeConnection(con,stmt);
273     }
274   }
275
276
277   public EntityList getContent(EntityTopics topic)
278     throws StorageObjectException {
279     EntityList returnList=null;
280     if (topic != null) {
281       String id = topic.getId();
282       String select = "select content_id from " + theTable + " where topic_id=" + id;
283
284       // execute select statement
285       Connection con=null;Statement stmt=null;
286       try {
287         con = getPooledCon();
288         // should be a preparedStatement because is faster
289         stmt = con.createStatement();
290         ResultSet rs = executeSql(stmt,select);
291         if (rs!=null) {
292           String topicSelect= "id IN (";
293           boolean first=true;
294           while (rs.next()) {
295             if (first==false) topicSelect+=",";
296             topicSelect += rs.getString(1);
297             first=false;
298           }
299           topicSelect+=")";
300           if (first==false)
301             returnList = DatabaseContent.getInstance().selectByWhereClause(topicSelect,-1);
302         }
303       }
304       catch (Exception e) {theLog.printDebugInfo("-- get contetn failed");}
305       finally { freeConnection(con,stmt);}
306     }
307     return returnList;
308   }
309 }