001 /*
002 *
003 * $Revision: 14986 $ $Date: 2009-03-20 21:41:45 +0100 (Fri, 20 Mar 2009) $
004 *
005 * This file is part of *** M y C o R e ***
006 * See http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, in a file called gpl.txt or license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 */
023
024 package org.mycore.datamodel.common;
025
026 import java.util.Collection;
027 import java.util.Collections;
028 import java.util.LinkedList;
029 import java.util.Map;
030
031 import org.apache.log4j.Logger;
032 import org.mycore.common.MCRConfiguration;
033 import org.mycore.common.MCRException;
034 import org.mycore.datamodel.metadata.MCRObjectID;
035
036 /**
037 * This class manage all accesses to the link table database. This database
038 * holds all informations about links between MCRObjects/MCRClassifications.
039 *
040 * @author Jens Kupferschmidt
041 * @version $Revision: 14986 $ $Date: 2009-03-20 21:41:45 +0100 (Fri, 20 Mar 2009) $
042 */
043 public class MCRLinkTableManager {
044 /** The list of entry types */
045 public static final String ENTRY_TYPE_CHILD = "child";
046
047 public static final String ENTRY_TYPE_DERIVATE = "derivate";
048
049 public static final String ENTRY_TYPE_PARENT = "parent";
050
051 public static final String ENTRY_TYPE_REFERENCE = "reference";
052
053 /** The link table manager singleton */
054 protected static MCRLinkTableManager singleton;
055
056 // logger
057 static Logger logger = Logger.getLogger(MCRLinkTableManager.class.getName());
058
059 // the persitence class
060 private String persistclassname = null;
061
062 private MCRLinkTableInterface persistenceclass = null;
063
064 /**
065 * Returns the link table manager singleton.
066 *
067 * @return Returns a MCRLinkTableManager instance.
068 */
069 public static synchronized MCRLinkTableManager instance() {
070 if (singleton == null) {
071 singleton = new MCRLinkTableManager();
072 }
073
074 return singleton;
075 }
076
077 /**
078 * The constructor of this class.
079 */
080 protected MCRLinkTableManager() {
081 MCRConfiguration config = MCRConfiguration.instance();
082
083 // Load the persistence class
084 persistclassname = config.getString("MCR.Persistence.LinkTable.Store.Class");
085
086 Object obj = new Object();
087 try {
088 obj = Class.forName(persistclassname).newInstance();
089 } catch (ClassNotFoundException e) {
090 throw new MCRException(persistclassname + " ClassNotFoundException");
091 } catch (IllegalAccessException e) {
092 throw new MCRException(persistclassname + " IllegalAccessException");
093 } catch (InstantiationException e) {
094 throw new MCRException(persistclassname + " InstantiationException");
095 }
096
097 persistenceclass = (MCRLinkTableInterface) obj;
098 }
099
100 /**
101 * This method check the type of link.
102 *
103 * @param type
104 * @return true if it is a defined type, else return false and send a
105 * warning to the logger.
106 */
107 private final boolean checkType(String type) {
108 if (type.equals(ENTRY_TYPE_CHILD) || type.equals(ENTRY_TYPE_DERIVATE) || type.equals(ENTRY_TYPE_PARENT) || type.equals(ENTRY_TYPE_REFERENCE)) {
109 return true;
110 }
111 logger.warn("The value " + type + " is not a defined type for the link table.");
112 return false;
113 }
114
115 /**
116 * The method add a reference link pair.
117 *
118 * @param from
119 * the source of the reference as MCRObjectID
120 * @param to
121 * the target of the reference as MCRObjectID
122 * @param type
123 * the type of the reference as String
124 * @param attr
125 * the optional attribute of the reference as String
126 */
127 public void addReferenceLink(MCRObjectID from, MCRObjectID to, String type, String attr) {
128 addReferenceLink(from.getId(), to.getId(), type, attr);
129 }
130
131 /**
132 * The method add a reference link pair.
133 *
134 * @param from
135 * the source of the reference as String
136 * @param to
137 * the target of the reference as String
138 * @param type
139 * the type of the reference as String
140 * @param attr
141 * the optional attribute of the reference as String
142 */
143 public void addReferenceLink(String from, String to, String type, String attr) {
144 if ((from == null) || ((from = from.trim()).length() == 0)) {
145 logger.warn("The from value of a reference link is false, the link was not added to the link table");
146 return;
147 }
148
149 if ((to == null) || ((to = to.trim()).length() == 0)) {
150 logger.warn("The to value of a reference link is false, the link was not added to the link table");
151 return;
152 }
153
154 if ((type == null) || ((type = type.trim()).length() == 0)) {
155 logger.warn("The type value of a reference link is false, the link was not added to the link table");
156 return;
157 }
158
159 if (attr == null) {
160 attr = "";
161 }
162
163 StringBuffer sb = new StringBuffer().append("Link in table ").append(type).append(" add for ").append(from).append("<-->").append(to).append(" with ")
164 .append(type).append(" and ").append(attr);
165 logger.debug(sb.toString());
166
167 try {
168 persistenceclass.create(from, to, type, attr);
169 } catch (Exception e) {
170 if (logger.isDebugEnabled()) {
171 e.printStackTrace();
172 }
173 logger.warn("An error occured while adding a dataset from the reference link table, adding not succesful.");
174 }
175 }
176
177 /**
178 * The method delete a reference link.
179 *
180 * @param from
181 * the source of the reference as MCRObjectID
182 */
183 public void deleteReferenceLink(MCRObjectID from) {
184 deleteReferenceLink(from.getId());
185 }
186
187 /**
188 * The method delete a reference link.
189 *
190 * @param from
191 * the source of the reference as String
192 */
193 public void deleteReferenceLink(String from) {
194 if ((from == null) || ((from = from.trim()).length() == 0)) {
195 logger.warn("The from value of a reference link is false, the link was " + "not deleted from the link table");
196 return;
197 }
198
199 try {
200 persistenceclass.delete(from, null, null);
201 } catch (Exception e) {
202 if (logger.isDebugEnabled()) {
203 e.printStackTrace();
204 }
205 logger.warn("An error occured while deleting a dataset from the" + from + " reference link table, deleting could be not succesful.");
206 }
207 }
208
209 /**
210 * The method delete a reference link pair for the given type to the store.
211 *
212 * @param from
213 * the source of the reference as String
214 * @param to
215 * the target of the reference as String
216 * @param type
217 * the type of the reference as String
218 */
219 public void deleteReferenceLink(String from, String to, String type) {
220 if ((from == null) || ((from = from.trim()).length() == 0)) {
221 logger.warn("The from value of a reference link is false, the link was " + "not deleted from the link table");
222 return;
223 }
224 try {
225 persistenceclass.delete(from, to, type);
226 } catch (Exception e) {
227 e.printStackTrace();
228 logger.warn("An error occured while deleting a dataset from the" + " reference link table, deleting is not succesful.");
229 }
230 }
231
232 /**
233 * The method count the reference links for a given target MCRobjectID.
234 *
235 * @param to
236 * the object ID as MCRObjectID, they was referenced
237 * @return the number of references
238 */
239 public int countReferenceLinkTo(MCRObjectID to) {
240 return countReferenceLinkTo(to.getId());
241 }
242
243 /**
244 * The method count the reference links for a given target object ID.
245 *
246 * @param to
247 * the object ID as String, they was referenced
248 * @return the number of references
249 */
250 public int countReferenceLinkTo(String to) {
251 if ((to == null) || ((to = to.trim()).length() == 0)) {
252 logger.warn("The to value of a reference link is false, the link was " + "not added to the link table");
253
254 return 0;
255 }
256
257 try {
258 return persistenceclass.countTo(null, to, null, null);
259 } catch (Exception e) {
260 logger.warn("An error occured while searching for references of " + to + ".");
261 }
262
263 return 0;
264 }
265
266 /**
267 * counts the reference links for a given to object ID.
268 *
269 * @param types
270 * Array of document type slected by the mcrfrom content
271 * @param restriction
272 * a first part of the to ID as String, it can be null
273 * @return the number of references
274 */
275 public int countReferenceLinkTo(String to, String[] types, String restriction) {
276 if ((to == null) || ((to = to.trim()).length() == 0)) {
277 logger.warn("The to value of a reference link is false, the link was " + "not added to the link table");
278 return 0;
279 }
280
281 try {
282 if (((types != null) && (types.length > 0))) {
283 String mydoctype = "";
284 int cnt = 0;
285 int idt = 0;
286
287 for (idt = 0; idt < types.length; idt++) {
288 mydoctype = types[idt];
289 cnt += persistenceclass.countTo(null, to, mydoctype, restriction);
290 }
291
292 return cnt;
293 }
294 return persistenceclass.countTo(null, to, null, restriction);
295 } catch (Exception e) {
296 logger.warn("An error occured while searching for references of " + to + ".");
297 }
298
299 return 0;
300 }
301
302 /**
303 * The method count the number of references to a category of a
304 * classification without sub ID's and returns it as a Map
305 *
306 * @param classid
307 * the classification ID as MCRObjectID
308 *
309 * @return a Map with key=categID and value=counted number of references
310 */
311 public Map<String, Number> countReferenceCategory(String classid) {
312 return persistenceclass.getCountedMapOfMCRTO(classid);
313 }
314
315 /**
316 * The method count the number of references to a category of a
317 * classification.
318 *
319 * @param classid
320 * the classification ID as String
321 * @param categid
322 * the category ID as String
323 * @return the number of references
324 */
325 public int countReferenceCategory(String classid, String categid) {
326 return countReferenceLinkTo(classid + "##" + categid, null, null);
327 }
328
329 /**
330 * Returns a List of all link sources of <code>to</code>
331 *
332 * @param to
333 * The MCRObjectID to referenced.
334 * @return List of Strings (Source-IDs)
335 */
336 public Collection<String> getSourceOf(MCRObjectID to) {
337 return getSourceOf(to.getId());
338 }
339
340 /**
341 * Returns a List of all link sources of <code>to</code>
342 *
343 * @param to
344 * The ID to referenced.
345 * @return List of Strings (Source-IDs)
346 */
347 public Collection<String> getSourceOf(String to) {
348 if ((to == null) || (to.length() == 0)) {
349 logger.warn("The to value of a reference link is false, the link was not found in the link table");
350 return Collections.emptyList();
351 }
352
353 try {
354 return persistenceclass.getSourcesOf(to, null);
355 } catch (Exception e) {
356 logger.warn("An error occured while searching for references to " + to + ".");
357 return Collections.emptyList();
358 }
359 }
360
361 /**
362 * Returns a List of all link sources of <code>to</code> and a special
363 * <code>type</code>
364 *
365 * @param to
366 * Destination-ID
367 * @param type
368 * link reference type
369 * @return List of Strings (Source-IDs)
370 */
371 public Collection<String> getSourceOf(MCRObjectID to, String type) {
372 return getSourceOf(to.getId(), type);
373 }
374
375 /**
376 * Returns a List of all link sources of <code>to</code> and a special
377 * <code>type</code>
378 *
379 * @param to
380 * Destination-ID
381 * @param type
382 * link reference type
383 * @return List of Strings (Source-IDs)
384 */
385 public Collection<String> getSourceOf(String to, String type) {
386 if ((to == null) || (to.length() == 0)) {
387 logger.warn("The to value of a reference link is false, the link was not found in the link table");
388 return Collections.emptyList();
389 }
390 if ((type == null) || (type.length() == 0)) {
391 logger.warn("The type value of a reference link is false, the link was not found in the link table");
392 return Collections.emptyList();
393 }
394 checkType(type);
395
396 try {
397 return persistenceclass.getSourcesOf(to, type);
398 } catch (Exception e) {
399 logger.warn("An error occured while searching for references to " + to + " with " + type + ".");
400 return Collections.emptyList();
401 }
402 }
403
404 /**
405 * The method return a list of all source ID's of the refernce target to
406 * with the given type.
407 *
408 * @param to
409 * the refernce target to
410 * @param type
411 * type of the refernce
412 * @return a list of ID's
413 */
414 public Collection<String> getSourceOf(String[] to, String type) {
415 if ((to == null) || (to.length == 0)) {
416 logger.warn("The to value of a reference link is false, the link was not found in the link table");
417 return Collections.emptyList();
418 }
419 LinkedList<String> ll = new LinkedList<String>();
420 try {
421 for (String singleTo : to) {
422 ll.addAll(persistenceclass.getSourcesOf(singleTo, type));
423 }
424 return ll;
425 } catch (Exception e) {
426 logger.warn("An error occured while searching for references to " + to + ".");
427 return ll;
428 }
429 }
430
431 /**
432 * Returns a List of all link destinations of <code>from</code> and a
433 * special <code>type</code>
434 *
435 * @param from
436 * Destination-ID
437 * @param type
438 * link reference type
439 * @return List of Strings (Source-IDs)
440 */
441 public Collection<String> getDestinationOf(MCRObjectID from, String type) {
442 return getDestinationOf(from.getId(), type);
443 }
444
445 /**
446 * Returns a List of all link destination of <code>from</code> and a
447 * special <code>type</code>
448 *
449 * @param from
450 * Source-ID
451 * @param type
452 * Link reference type, this can be null. Current types are
453 * classid, child, parent, reference and derivate.
454 * @return List of Strings (Destination-IDs)
455 */
456 public Collection<String> getDestinationOf(String from, String type) {
457 if ((from == null) || (from.length() == 0)) {
458 logger.warn("The to value of a reference link is false, the link was not found in the link table");
459 return Collections.emptyList();
460 }
461 if ((type == null) || (type.length() == 0)) {
462 logger.warn("The type value of a reference link is false, the link was not found in the link table");
463 return Collections.emptyList();
464 }
465 checkType(type);
466
467 try {
468 return persistenceclass.getDestinationsOf(from, type);
469 } catch (Exception e) {
470 logger.warn("An error occured while searching for references from " + from + ".");
471 return Collections.emptyList();
472 }
473 }
474
475 }