0001: /*--------------------------------------------------------------------------*
0002: | Copyright (C) 2006 Christopher Kohlhaas |
0003: | |
0004: | This program is free software; you can redistribute it and/or modify |
0005: | it under the terms of the GNU General Public License as published by the |
0006: | Free Software Foundation. A copy of the license has been included with |
0007: | these distribution in the COPYING file, if not go to www.fsf.org . |
0008: | |
0009: | As a special exception, you are granted the permissions to link this |
0010: | program with every library, of which license fullfill the Open Source |
0011: | Definition as published by the Open Source Initiative (OSI). |
0012: *--------------------------------------------------------------------------*/
0013: package org.rapla.storage.dbsql;
0014:
0015: import java.io.BufferedWriter;
0016: import java.io.IOException;
0017: import java.io.StringWriter;
0018: import java.sql.Connection;
0019: import java.sql.PreparedStatement;
0020: import java.sql.ResultSet;
0021: import java.sql.SQLException;
0022: import java.sql.Timestamp;
0023: import java.text.ParseException;
0024: import java.util.ArrayList;
0025: import java.util.Comparator;
0026: import java.util.Date;
0027: import java.util.HashMap;
0028: import java.util.Iterator;
0029: import java.util.List;
0030: import java.util.ListIterator;
0031: import java.util.Map;
0032: import java.util.TreeMap;
0033:
0034: import org.apache.avalon.framework.logger.Logger;
0035: import org.rapla.components.util.Assert;
0036: import org.rapla.entities.Category;
0037: import org.rapla.entities.EntityNotFoundException;
0038: import org.rapla.entities.RaplaObject;
0039: import org.rapla.entities.RaplaType;
0040: import org.rapla.entities.User;
0041: import org.rapla.entities.configuration.Preferences;
0042: import org.rapla.entities.configuration.internal.PreferencesImpl;
0043: import org.rapla.entities.domain.Allocatable;
0044: import org.rapla.entities.domain.Appointment;
0045: import org.rapla.entities.domain.Period;
0046: import org.rapla.entities.domain.Permission;
0047: import org.rapla.entities.domain.Repeating;
0048: import org.rapla.entities.domain.RepeatingType;
0049: import org.rapla.entities.domain.Reservation;
0050: import org.rapla.entities.domain.internal.AllocatableImpl;
0051: import org.rapla.entities.domain.internal.AppointmentImpl;
0052: import org.rapla.entities.domain.internal.PeriodImpl;
0053: import org.rapla.entities.domain.internal.PermissionImpl;
0054: import org.rapla.entities.domain.internal.ReservationImpl;
0055: import org.rapla.entities.dynamictype.Attribute;
0056: import org.rapla.entities.dynamictype.Classifiable;
0057: import org.rapla.entities.dynamictype.Classification;
0058: import org.rapla.entities.dynamictype.DynamicType;
0059: import org.rapla.entities.dynamictype.internal.AttributeImpl;
0060: import org.rapla.entities.internal.CategoryImpl;
0061: import org.rapla.entities.internal.UserImpl;
0062: import org.rapla.entities.storage.RefEntity;
0063: import org.rapla.entities.storage.internal.SimpleIdentifier;
0064: import org.rapla.framework.RaplaContext;
0065: import org.rapla.framework.RaplaException;
0066: import org.rapla.storage.xml.CategoryReader;
0067: import org.rapla.storage.xml.PreferenceReader;
0068: import org.rapla.storage.xml.RaplaXMLReader;
0069: import org.rapla.storage.xml.RaplaXMLWriter;
0070: import org.xml.sax.SAXException;
0071:
0072: class RaplaSQL {
0073: private List stores = new ArrayList();
0074: private Logger logger;
0075:
0076: RaplaSQL(RaplaContext context, boolean oldResourceTable)
0077: throws RaplaException {
0078: logger = (Logger) context.lookup(Logger.class.getName());
0079: // The order is important. e.g. appointments can only be loaded if the reservation they are refering to are already loaded.
0080: stores.add(new CategoryStorage(context));
0081: stores.add(new DynamicTypeStorage(context));
0082: stores.add(new UserStorage(context));
0083: stores.add(new AllocatableStorage(context, oldResourceTable));
0084: stores.add(new PreferenceStorage(context));
0085: stores.add(new PeriodStorage(context));
0086: stores.add(new ReservationStorage(context));
0087: stores.add(new AppointmentStorage(context));
0088: }
0089:
0090: protected Logger getLogger() {
0091: return logger;
0092: }
0093:
0094: /***************************************************
0095: * Create everything *
0096: ***************************************************/
0097: synchronized public void createAll(Connection con)
0098: throws SQLException, RaplaException {
0099: getLogger().info("Inserting Data in Database");
0100: Iterator it = stores.iterator();
0101: while (it.hasNext()) {
0102: Storage storage = (Storage) it.next();
0103: storage.setConnection(con);
0104: ((RaplaTypeStorage) storage).insertAll();
0105: }
0106: }
0107:
0108: synchronized public void removeAll(Connection con)
0109: throws SQLException, RaplaException {
0110: getLogger().info("Deleting all Data in Database");
0111: ListIterator listIt = stores.listIterator(stores.size());
0112: while (listIt.hasPrevious()) {
0113: Storage storage = (Storage) listIt.previous();
0114: storage.setConnection(con);
0115: storage.deleteAll();
0116: }
0117: }
0118:
0119: synchronized public void loadAll(Connection con)
0120: throws SQLException, RaplaException {
0121: Iterator it = stores.iterator();
0122: while (it.hasNext()) {
0123: Storage storage = (Storage) it.next();
0124: storage.setConnection(con);
0125: storage.loadAll();
0126: }
0127: }
0128:
0129: synchronized public void remove(Connection con, RefEntity entity)
0130: throws SQLException, RaplaException {
0131: if (Attribute.TYPE.equals(entity.getRaplaType()))
0132: return;
0133: Iterator it = stores.iterator();
0134: while (it.hasNext()) {
0135: Storage storage = (Storage) it.next();
0136: if (((RaplaTypeStorage) storage).canStore(entity)) {
0137: storage.setConnection(con);
0138: storage.delete((RefEntity) entity);
0139: return;
0140: }
0141: }
0142: throw new RaplaException(
0143: "No Storage-Sublass matches this object: "
0144: + entity.getClass());
0145: }
0146:
0147: synchronized public void store(Connection con, RaplaObject entity)
0148: throws SQLException, RaplaException {
0149: if (Attribute.TYPE.equals(entity.getRaplaType()))
0150: return;
0151: Iterator it = stores.iterator();
0152: while (it.hasNext()) {
0153: Storage storage = (Storage) it.next();
0154: if (((RaplaTypeStorage) storage).canStore(entity)) {
0155: storage.setConnection(con);
0156: storage.save((RefEntity) entity);
0157: return;
0158: }
0159: }
0160: throw new RaplaException(
0161: "No Storage-Sublass matches this object: "
0162: + entity.getClass());
0163: }
0164: }
0165:
0166: abstract class RaplaTypeStorage extends EntityStorage {
0167: RaplaType raplaType;
0168:
0169: RaplaTypeStorage(RaplaContext context, RaplaType raplaType,
0170: String tableName, String[] entries) throws RaplaException {
0171: super (context, tableName, entries);
0172: this .raplaType = raplaType;
0173: }
0174:
0175: boolean canStore(RaplaObject entity) {
0176: return entity.getRaplaType().is(raplaType);
0177: }
0178:
0179: void insertAll() throws SQLException, RaplaException {
0180: insert(cache.getCollection(raplaType));
0181: }
0182:
0183: protected String getXML(RaplaObject type) throws RaplaException {
0184: RaplaXMLWriter dynamicTypeWriter = getWriterFor(type
0185: .getRaplaType());
0186: StringWriter stringWriter = new StringWriter();
0187: BufferedWriter bufferedWriter = new BufferedWriter(stringWriter);
0188: dynamicTypeWriter.setWriter(bufferedWriter);
0189: try {
0190: dynamicTypeWriter.writeObject(type);
0191: bufferedWriter.flush();
0192: } catch (IOException ex) {
0193: throw new RaplaException(ex);
0194: }
0195: return stringWriter.getBuffer().toString();
0196:
0197: }
0198:
0199: protected RaplaXMLReader processXML(RaplaType type, String xml)
0200: throws RaplaException {
0201: RaplaXMLReader contentHandler = getReaderFor(type);
0202: if (xml == null || xml.trim().length() <= 10) {
0203: throw new RaplaException("Can't load " + type);
0204: }
0205: try {
0206: getReader().readWithNamespaces(xml, contentHandler);
0207: } catch (IOException ex) {
0208: throw new RaplaException(ex);
0209: }
0210: return contentHandler;
0211: }
0212:
0213: }
0214:
0215: class PeriodStorage extends RaplaTypeStorage {
0216: public PeriodStorage(RaplaContext context) throws RaplaException {
0217: super (context, Period.TYPE, "PERIOD", new String[] { "ID",
0218: "NAME", "PERIOD_START", "PERIOD_END" });
0219: }
0220:
0221: protected void write(PreparedStatement stmt, RefEntity entity)
0222: throws SQLException {
0223: Period s = (Period) entity;
0224: if (getLogger().isDebugEnabled())
0225: getLogger().debug("Inserting Period " + s.getName());
0226: stmt.setInt(1, getId(entity));
0227: stmt.setString(2, s.getName());
0228: stmt.setTimestamp(3, new java.sql.Timestamp(s.getStart()
0229: .getTime()));
0230: stmt.setTimestamp(4, new java.sql.Timestamp(s.getEnd()
0231: .getTime()));
0232: stmt.executeUpdate();
0233: }
0234:
0235: protected void load(ResultSet rset) throws SQLException {
0236: SimpleIdentifier id = new SimpleIdentifier(Period.TYPE, rset
0237: .getInt(1));
0238: String name = getString(rset, 2);
0239: java.util.Date von = new java.util.Date(rset.getTimestamp(3)
0240: .getTime());
0241: java.util.Date bis = new java.util.Date(rset.getTimestamp(4)
0242: .getTime());
0243: PeriodImpl period = new PeriodImpl(von, bis);
0244: period.setName(name);
0245: period.setId(id);
0246: put(period);
0247: if (getLogger().isDebugEnabled()) {
0248: getLogger().debug(" " + name);
0249: getLogger().debug(" start: " + von);
0250: getLogger().debug(" end: " + bis);
0251: }
0252: }
0253: }
0254:
0255: class CategoryStorage extends RaplaTypeStorage {
0256: Map orderMap = new HashMap();
0257: Map categoriesWithoutParent = new TreeMap(new Comparator() {
0258: public int compare(Object o1, Object o2) {
0259: if (o1.equals(o2)) {
0260: return 0;
0261: }
0262: int ordering1 = ((Integer) orderMap.get(o1)).intValue();
0263: int ordering2 = ((Integer) orderMap.get(o2)).intValue();
0264: if (ordering1 < ordering2) {
0265: return -1;
0266: }
0267: if (ordering1 > ordering2) {
0268: return 1;
0269: }
0270: RefEntity e1 = (RefEntity) o1;
0271: RefEntity e2 = (RefEntity) o2;
0272: if (e1.hashCode() > e2.hashCode()) {
0273: return -1;
0274: } else {
0275: return 1;
0276: }
0277: }
0278:
0279: });
0280:
0281: public CategoryStorage(RaplaContext context) throws RaplaException {
0282: super (context, Category.TYPE, "CATEGORY", new String[] { "ID",
0283: "PARENT_ID", "CATEGORY_KEY", "LABEL", "DEFINITION",
0284: "PARENT_ORDER" });
0285: }
0286:
0287: protected void write(PreparedStatement stmt, RefEntity entity)
0288: throws SQLException, RaplaException {
0289: Category root = getSuperCategory();
0290: if (entity.equals(root))
0291: return;
0292: Category category = (Category) entity;
0293: String name = category.getName(getLocale());
0294: int id = getId(entity);
0295: int parentId = getId((RefEntity) category.getParent());
0296: if (getLogger().isDebugEnabled())
0297: getLogger().debug("Inserting Category " + name);
0298: stmt.setInt(1, id);
0299: if (root.equals(category.getParent())) {
0300: stmt.setObject(2, null);
0301: } else {
0302: stmt.setInt(2, parentId);
0303: }
0304: int order = getOrder(category);
0305: String xml = getXML(category);
0306: stmt.setString(3, category.getKey());
0307: stmt.setString(4, name);
0308: stmt.setString(5, xml);
0309: stmt.setInt(6, order);
0310: stmt.executeUpdate();
0311: }
0312:
0313: private int getOrder(Category category) {
0314: Category parent = category.getParent();
0315: if (parent == null) {
0316: return 0;
0317: }
0318: Category[] childs = parent.getCategories();
0319: ;
0320: for (int i = 0; i < childs.length; i++) {
0321: if (childs[i].equals(category)) {
0322: return i;
0323: }
0324: }
0325: getLogger().error("Category not found in parent");
0326: return 0;
0327: }
0328:
0329: public RaplaXMLReader getReaderFor(RaplaType type)
0330: throws RaplaException {
0331: RaplaXMLReader reader = super .getReaderFor(type);
0332: if (type.equals(Category.TYPE)) {
0333: ((CategoryReader) reader).setReadOnlyThisCategory(true);
0334: }
0335: return reader;
0336: }
0337:
0338: protected void load(ResultSet rset) throws SQLException,
0339: RaplaException {
0340: int idInt = rset.getInt(1);
0341: String key = getString(rset, 3);
0342: String name = getString(rset, 4);
0343: String xml = getString(rset, 5);
0344: Object id = new SimpleIdentifier(Category.TYPE, idInt);
0345: int order = rset.getInt(6);
0346: CategoryImpl category;
0347: if (xml != null && xml.length() > 10) {
0348: category = ((CategoryReader) processXML(Category.TYPE, xml))
0349: .getCurrentCategory();
0350: //cache.remove( category );
0351: category.setId(id);
0352: } else {
0353: // for compatibility with version prior to 1.0rc1
0354: category = new CategoryImpl();
0355: category.setId(id);
0356: category.setKey(key);
0357: category.getName().setName(getLocale().getLanguage(), name);
0358: }
0359:
0360: put(category);
0361:
0362: int parentIdInt = rset.getInt(2);
0363: orderMap.put(category, new Integer(order));
0364: if (!rset.wasNull()) {
0365: categoriesWithoutParent.put(category, new SimpleIdentifier(
0366: Category.TYPE, parentIdInt));
0367: } else {
0368: categoriesWithoutParent.put(category, null);
0369: }
0370: }
0371:
0372: public void loadAll() throws RaplaException, SQLException {
0373: categoriesWithoutParent.clear();
0374: super .loadAll();
0375: // then we rebuild the hirarchy
0376: Iterator it = categoriesWithoutParent.entrySet().iterator();
0377: while (it.hasNext()) {
0378: Map.Entry entry = (Map.Entry) it.next();
0379: Object parentId = entry.getValue();
0380: Category category = (Category) entry.getKey();
0381: Category parent;
0382: Assert.notNull(category);
0383: if (parentId != null) {
0384: parent = (Category) resolve(parentId);
0385: Assert.notNull(parent);
0386: } else {
0387: parent = getSuperCategory();
0388: Assert.notNull(parent);
0389: }
0390:
0391: parent.addCategory(category);
0392: }
0393: }
0394: }
0395:
0396: class AllocatableStorage extends RaplaTypeStorage {
0397: Map classificationMap = new HashMap();
0398: Map allocatableMap = new HashMap();
0399: AttributeValueStorage resourceAttributeStorage;
0400: PermissionStorage permissionStorage;
0401:
0402: public AllocatableStorage(RaplaContext context,
0403: boolean oldResourceTable) throws RaplaException {
0404: super (context, Allocatable.TYPE, oldResourceTable ? "RESOURCE"
0405: : "RAPLA_RESOURCE", new String[] { "ID", "TYPE_KEY",
0406: "IS_PERSON", "IGNORE_CONFLICTS" });
0407: resourceAttributeStorage = new AttributeValueStorage(context,
0408: "RESOURCE_ATTRIBUTE_VALUE", "RESOURCE_ID",
0409: classificationMap);
0410: permissionStorage = new PermissionStorage(context,
0411: allocatableMap);
0412: addSubStorage(resourceAttributeStorage);
0413: addSubStorage(permissionStorage);
0414: }
0415:
0416: protected void write(PreparedStatement stmt, RefEntity entity)
0417: throws SQLException, RaplaException {
0418: AllocatableImpl resource = (AllocatableImpl) entity;
0419: if (getLogger().isDebugEnabled())
0420: getLogger().debug(
0421: "Inserting Resource "
0422: + resource.getName(getLocale()));
0423: int id = getId(entity);
0424: String typeKey = resource.getClassification().getType()
0425: .getElementKey();
0426: stmt.setInt(1, id);
0427: stmt.setString(2, typeKey);
0428: stmt.setInt(3, resource.isPerson() ? 1 : 0);
0429: stmt.setInt(4, resource.isHoldBackConflicts() ? 1 : 0);
0430: stmt.executeUpdate();
0431: }
0432:
0433: protected void load(ResultSet rset) throws SQLException {
0434: int idInt = rset.getInt(1);
0435: String typeKey = rset.getString(2);
0436: boolean isPerson = rset.getInt(3) == 1;
0437: boolean ignoreConflicts = rset.getInt(4) == 1;
0438:
0439: AllocatableImpl allocatable = new AllocatableImpl();
0440: allocatable.setPerson(isPerson);
0441: allocatable.setId(new SimpleIdentifier(allocatable
0442: .getRaplaType(), idInt));
0443: allocatable.setHoldBackConflicts(ignoreConflicts);
0444: DynamicType type = getDynamicType(typeKey);
0445: if (type == null) {
0446: getLogger().error(
0447: "Allocatable with id " + idInt
0448: + " has an unknown type " + typeKey
0449: + ". Try ignoring it");
0450: return;
0451: }
0452:
0453: Classification classification = type.newClassification();
0454: allocatable.setClassification(classification);
0455: classificationMap.put(new Integer(idInt), classification);
0456: allocatableMap.put(new Integer(idInt), allocatable);
0457: put(allocatable);
0458: }
0459:
0460: public void loadAll() throws RaplaException, SQLException {
0461: classificationMap.clear();
0462: super .loadAll();
0463: }
0464: }
0465:
0466: class ReservationStorage extends RaplaTypeStorage {
0467: Map classificationMap = new HashMap();
0468: Map reservationMap = new HashMap();
0469: AttributeValueStorage attributeValueStorage;
0470:
0471: public ReservationStorage(RaplaContext context)
0472: throws RaplaException {
0473: super (context, Reservation.TYPE, "EVENT", new String[] { "ID",
0474: "TYPE_KEY", "OWNER_ID", "CREATION_TIME",
0475: "LAST_CHANGED", "LAST_CHANGED_BY" });
0476: attributeValueStorage = new AttributeValueStorage(context,
0477: "EVENT_ATTRIBUTE_VALUE", "EVENT_ID", classificationMap);
0478: addSubStorage(attributeValueStorage);
0479: }
0480:
0481: protected void write(PreparedStatement stmt, RefEntity entity)
0482: throws SQLException, RaplaException {
0483: Reservation event = (Reservation) entity;
0484: if (getLogger().isDebugEnabled())
0485: getLogger()
0486: .debug(
0487: "Storing Reservation "
0488: + event.getName(getLocale()));
0489: int id = getId(entity);
0490: String typeKey = event.getClassification().getType()
0491: .getElementKey();
0492: int userId = getId((RefEntity) event.getOwner());
0493: stmt.setInt(1, id);
0494: stmt.setString(2, typeKey);
0495: stmt.setInt(3, userId);
0496: Date creationTime = event.getCreateTime();
0497: Date lastModified = event.getLastChangeTime();
0498: stmt.setTimestamp(4, new java.sql.Timestamp(creationTime
0499: .getTime()));
0500: stmt.setTimestamp(5, new java.sql.Timestamp(lastModified
0501: .getTime()));
0502: User lastChangedBy = event.getLastChangedBy();
0503: if (lastChangedBy != null) {
0504: int lastChangedById = getId((RefEntity) lastChangedBy);
0505: stmt.setInt(6, lastChangedById);
0506: } else {
0507: stmt.setObject(6, null);
0508: }
0509: stmt.executeUpdate();
0510: }
0511:
0512: protected void load(ResultSet rset) throws SQLException {
0513: int idInt = rset.getInt(1);
0514: String typeKey = rset.getString(2);
0515: int userInt = rset.getInt(3);
0516: java.sql.Timestamp creationTime = rset.getTimestamp(4);
0517: java.sql.Timestamp lastModified = rset.getTimestamp(5);
0518: ReservationImpl event = new ReservationImpl(new Date(
0519: creationTime.getTime()), new Date(lastModified
0520: .getTime()));
0521: event.setId(new SimpleIdentifier(Reservation.TYPE, idInt));
0522: DynamicType type = getDynamicType(typeKey);
0523: User user = (User) get(new SimpleIdentifier(User.TYPE, userInt));
0524: if (user == null || type == null) {
0525: getLogger()
0526: .warn(
0527: "Reservation with id "
0528: + idInt
0529: + " has no type or owner. It will be ignored");
0530: return;
0531: }
0532: event.setOwner(user);
0533: int lastModfiedByIdInt = rset.getInt(6);
0534: if (!rset.wasNull()) {
0535: User lastModifiedBy = (User) get(new SimpleIdentifier(
0536: User.TYPE, lastModfiedByIdInt));
0537: if (lastModifiedBy != null) {
0538: event.setLastChangedBy(lastModifiedBy);
0539: }
0540: }
0541:
0542: Classification classification = type.newClassification();
0543: event.setClassification(classification);
0544: classificationMap.put(new Integer(idInt), classification);
0545: reservationMap.put(new Integer(idInt), event);
0546: put(event);
0547: }
0548:
0549: public void loadAll() throws RaplaException, SQLException {
0550: classificationMap.clear();
0551: super .loadAll();
0552: }
0553: }
0554:
0555: /** This class should only be used whitin the ResourceStorage class*/
0556: class AttributeValueStorage extends EntityStorage {
0557: Map classificationMap;
0558: final String foreignKeyName;
0559:
0560: public AttributeValueStorage(RaplaContext context,
0561: String tablename, String foreignKeyName,
0562: Map classificationMap) throws RaplaException {
0563: super (context, tablename, new String[] { foreignKeyName,
0564: "ATTRIBUTE_KEY", "VALUE" });
0565: this .foreignKeyName = foreignKeyName;
0566: this .classificationMap = classificationMap;
0567: }
0568:
0569: protected void write(PreparedStatement stmt, RefEntity classifiable)
0570: throws EntityNotFoundException, SQLException {
0571: int id = getId(classifiable);
0572: Classification classification = ((Classifiable) classifiable)
0573: .getClassification();
0574: ;
0575: Attribute[] attributes = classification.getAttributes();
0576: for (int i = 0; i < attributes.length; i++) {
0577: Attribute attribute = attributes[i];
0578: Object value = classification.getValue(attribute);
0579: if (value == null) {
0580: continue;
0581: }
0582:
0583: String valueAsString = AttributeImpl
0584: .attributeValueToString(attribute, value, true);
0585: if (valueAsString == null) {
0586: continue;
0587: }
0588:
0589: stmt.setInt(1, id);
0590: stmt.setString(2, attribute.getKey());
0591: stmt.setString(3, valueAsString);
0592: stmt.execute();
0593: }
0594: }
0595:
0596: public void save(RefEntity entity) throws RaplaException,
0597: SQLException {
0598: delete(entity);
0599: insert(entity);
0600: }
0601:
0602: protected void load(ResultSet rset) throws SQLException,
0603: RaplaException {
0604: int classifiableIdInt = rset.getInt(1);
0605: String attributekey = rset.getString(2);
0606: Classification classification = (Classification) classificationMap
0607: .get(new Integer(classifiableIdInt));
0608: if (classification == null) {
0609: getLogger().warn(
0610: "No resource or reservation found for the id"
0611: + classifiableIdInt + " ignoring.");
0612: return;
0613: }
0614: Attribute attribute = classification.getType().getAttribute(
0615: attributekey);
0616: if (attribute == null) {
0617: throw new EntityNotFoundException("DynamicType '"
0618: + classification.getType()
0619: + "' doesnt have an attribute with the key "
0620: + attributekey + " Current Allocatable Id "
0621: + classifiableIdInt);
0622: }
0623: String valueAsString = rset.getString(3);
0624: Object value = null;
0625: try {
0626: if (valueAsString != null) {
0627: value = AttributeImpl.parseAttributeValue(attribute,
0628: valueAsString, getResolver());
0629: classification.setValue(attributekey, value);
0630: }
0631: } catch (ParseException ex) {
0632: throw new RaplaException("Error parsing attribute value: "
0633: + ex.getMessage(), ex);
0634: }
0635: }
0636:
0637: public void delete(RefEntity entity) throws SQLException {
0638: int classifiableId = getId(entity);
0639: executeBatchedStatement(con, "DELETE FROM " + tableName
0640: + " WHERE " + foreignKeyName + " = " + classifiableId);
0641: }
0642: }
0643:
0644: class PermissionStorage extends EntityStorage {
0645: Map allocatableMap;
0646:
0647: public PermissionStorage(RaplaContext context, Map allocatableMap)
0648: throws RaplaException {
0649: super (context, "PERMISSION", new String[] { "RESOURCE_ID",
0650: "USER_ID", "GROUP_ID", "ACCESS_LEVEL", "MIN_ADVANCE",
0651: "MAX_ADVANCE", "START_DATE", "END_DATE" });
0652: this .allocatableMap = allocatableMap;
0653: }
0654:
0655: protected void write(PreparedStatement stmt, RefEntity allocatable)
0656: throws SQLException, RaplaException {
0657: int resourceId = getId(allocatable);
0658: delete(allocatable);
0659: Permission[] permissions = ((Allocatable) allocatable)
0660: .getPermissions();
0661: for (int i = 0; i < permissions.length; i++) {
0662: Permission s = permissions[i];
0663: Category group = s.getGroup();
0664: User user = s.getUser();
0665: Date start = s.getStart();
0666: Date end = s.getEnd();
0667: Long minAdvance = s.getMinAdvance();
0668: Long maxAdvance = s.getMaxAdvance();
0669: stmt.setInt(1, resourceId);
0670: if (user != null) {
0671: int userId = getId((RefEntity) user);
0672: stmt.setInt(2, userId);
0673: } else {
0674: stmt.setObject(2, null);
0675: }
0676: if (group != null) {
0677: int groupId = getId((RefEntity) group);
0678: stmt.setInt(3, groupId);
0679: } else {
0680: stmt.setObject(3, null);
0681: }
0682: int accessLevel = s.getAccessLevel();
0683: stmt.setInt(4, accessLevel);
0684: if (minAdvance != null) {
0685: stmt.setInt(5, minAdvance.intValue());
0686: } else {
0687: stmt.setObject(5, null);
0688: }
0689: if (maxAdvance != null) {
0690: stmt.setInt(6, maxAdvance.intValue());
0691: } else {
0692: stmt.setObject(6, null);
0693: }
0694: if (start != null) {
0695: stmt.setTimestamp(7, new java.sql.Timestamp(start
0696: .getTime()));
0697: } else {
0698: stmt.setObject(7, null);
0699: }
0700: if (end != null) {
0701: stmt.setTimestamp(8, new java.sql.Timestamp(end
0702: .getTime()));
0703: } else {
0704: stmt.setObject(8, null);
0705: }
0706: stmt.executeUpdate();
0707: }
0708: }
0709:
0710: public void save(RefEntity entity) throws RaplaException,
0711: SQLException {
0712: delete(entity);
0713: insert(entity);
0714: }
0715:
0716: protected void load(ResultSet rset) throws SQLException,
0717: RaplaException {
0718: int allocatableIdInt = rset.getInt(1);
0719: Allocatable allocatable = (Allocatable) allocatableMap
0720: .get(new Integer(allocatableIdInt));
0721: PermissionImpl permission = new PermissionImpl();
0722: allocatable.addPermission(permission);
0723: int userIdInt = rset.getInt(2);
0724: if (!rset.wasNull()) {
0725: permission.getReferenceHandler().putId("user",
0726: new SimpleIdentifier(User.TYPE, userIdInt));
0727: }
0728: int groupIdInt = rset.getInt(3);
0729: if (!rset.wasNull()) {
0730: permission.getReferenceHandler().putId("group",
0731: new SimpleIdentifier(Category.TYPE, groupIdInt));
0732: }
0733: int accessLevel = rset.getInt(4);
0734: permission.setAccessLevel(accessLevel);
0735: int minAdvance = rset.getInt(5);
0736: if (!rset.wasNull()) {
0737: permission.setMinAdvance(new Long(minAdvance));
0738: }
0739: int maxAdvance = rset.getInt(6);
0740: if (!rset.wasNull()) {
0741: permission.setMaxAdvance(new Long(maxAdvance));
0742: }
0743: Timestamp startDate = rset.getTimestamp(7);
0744: if (!rset.wasNull()) {
0745: permission.setStart(new Date(startDate.getTime()));
0746: }
0747: Timestamp endDate = rset.getTimestamp(8);
0748: if (!rset.wasNull()) {
0749: permission.setEnd(new Date(endDate.getTime()));
0750: }
0751: }
0752:
0753: public void delete(RefEntity entity) throws SQLException {
0754: int resourceId = getId(entity);
0755: executeBatchedStatement(con, "DELETE FROM " + tableName
0756: + " WHERE RESOURCE_ID = " + resourceId);
0757: }
0758:
0759: }
0760:
0761: class AppointmentStorage extends RaplaTypeStorage {
0762: AppointmentExceptionStorage appointmentExceptionStorage;
0763: AllocationStorage allocationStorage;
0764:
0765: public AppointmentStorage(RaplaContext context)
0766: throws RaplaException {
0767: super (context, Appointment.TYPE, "APPOINTMENT", new String[] {
0768: "ID", "EVENT_ID", "APPOINTMENT_START",
0769: "APPOINTMENT_END", "REPETITION_TYPE",
0770: "REPETITION_NUMBER", "REPETITION_END",
0771: "REPETITION_INTERVAL" });
0772: appointmentExceptionStorage = new AppointmentExceptionStorage(
0773: context);
0774: allocationStorage = new AllocationStorage(context);
0775: addSubStorage(appointmentExceptionStorage);
0776: addSubStorage(allocationStorage);
0777: }
0778:
0779: protected void write(PreparedStatement stmt, RefEntity entity)
0780: throws SQLException, RaplaException {
0781: Appointment appointment = (Appointment) entity;
0782: int id = getId(entity);
0783: Timestamp start = new Timestamp(appointment.getStart()
0784: .getTime());
0785: Timestamp end = new Timestamp(appointment.getEnd().getTime());
0786: stmt.setInt(1, id);
0787: int parentId = getId((RefEntity) appointment.getReservation());
0788: stmt.setInt(2, parentId);
0789: stmt.setTimestamp(3, start);
0790: stmt.setTimestamp(4, end);
0791: Repeating repeating = appointment.getRepeating();
0792: if (repeating == null) {
0793: stmt.setObject(5, null);
0794: stmt.setObject(6, null);
0795: stmt.setObject(7, null);
0796: stmt.setObject(8, null);
0797: } else {
0798: stmt.setString(5, repeating.getType().toString());
0799: int number = repeating.getNumber();
0800: if (number >= 0) {
0801: stmt.setInt(6, number);
0802: } else {
0803: stmt.setObject(6, null);
0804: }
0805: Date repeatingEnd = repeating.getEnd();
0806: if (repeatingEnd != null) {
0807: stmt
0808: .setObject(7, new Timestamp(repeatingEnd
0809: .getTime()));
0810: } else {
0811: stmt.setObject(7, null);
0812: }
0813: int interval = repeating.getInterval();
0814: stmt.setInt(8, interval);
0815: }
0816: stmt.executeUpdate();
0817: }
0818:
0819: protected void load(ResultSet rset) throws SQLException,
0820: EntityNotFoundException {
0821: int idInt = rset.getInt(1);
0822: int parentId = rset.getInt(2);
0823: Reservation event;
0824: try {
0825: event = (Reservation) resolve(new SimpleIdentifier(
0826: Reservation.TYPE, parentId));
0827: } catch (EntityNotFoundException ex) {
0828: getLogger().warn(
0829: "Could not find reservation object with id "
0830: + parentId + " for appointment with id "
0831: + idInt);
0832: return;
0833: }
0834: Date start = new Date(rset.getTimestamp(3).getTime());
0835: Date end = new Date(rset.getTimestamp(4).getTime());
0836: AppointmentImpl appointment = new AppointmentImpl(start, end);
0837: appointment
0838: .setId(new SimpleIdentifier(Appointment.TYPE, idInt));
0839: event.addAppointment(appointment);
0840: String repeatingType = rset.getString(5);
0841: if (!rset.wasNull()) {
0842: appointment.setRepeatingEnabled(true);
0843: Repeating repeating = appointment.getRepeating();
0844: repeating.setType(RepeatingType
0845: .findForString(repeatingType));
0846: int number = rset.getInt(6);
0847: if (!rset.wasNull()) {
0848: repeating.setNumber(number);
0849: } else {
0850: java.sql.Timestamp repeatingEnd = rset.getTimestamp(7);
0851: if (!rset.wasNull()) {
0852: repeating.setEnd(new Date(repeatingEnd.getTime()));
0853: } else {
0854: repeating.setEnd(null);
0855: }
0856: }
0857:
0858: int interval = rset.getInt(8);
0859: if (!rset.wasNull())
0860: repeating.setInterval(interval);
0861: }
0862: put(appointment);
0863: }
0864: }
0865:
0866: class AllocationStorage extends EntityStorage {
0867:
0868: public AllocationStorage(RaplaContext context)
0869: throws RaplaException {
0870: super (context, "ALLOCATION", new String[] { "APPOINTMENT_ID",
0871: "RESOURCE_ID" });
0872: }
0873:
0874: protected void write(PreparedStatement stmt, RefEntity entity)
0875: throws SQLException, RaplaException {
0876: int appointmentId = getId(entity);
0877: Appointment appointment = (Appointment) entity;
0878: Reservation event = appointment.getReservation();
0879: Allocatable[] allocatables = event.getAllocatables();
0880: for (int j = 0; j < allocatables.length; j++) {
0881: Allocatable allocatable = allocatables[j];
0882: if (!event.hasAllocated(allocatable, appointment)) {
0883: continue;
0884: }
0885: int allocatableId = getId((RefEntity) allocatable);
0886: stmt.setInt(1, appointmentId);
0887: stmt.setInt(2, allocatableId);
0888: stmt.executeUpdate();
0889: }
0890: }
0891:
0892: public void save(RefEntity entity) throws RaplaException,
0893: SQLException {
0894: delete(entity);
0895: insert(entity);
0896: }
0897:
0898: protected void load(ResultSet rset) throws SQLException,
0899: RaplaException {
0900: int appointmentId = rset.getInt(1);
0901: int resourceId = rset.getInt(2);
0902: Appointment appointment;
0903: try {
0904: appointment = (Appointment) resolve(new SimpleIdentifier(
0905: Appointment.TYPE, appointmentId));
0906: } catch (EntityNotFoundException ex) {
0907: getLogger().warn(
0908: "Could not find appointment with id "
0909: + appointmentId
0910: + " for the allocation resource "
0911: + resourceId + ". Ignoring.");
0912: return;
0913: }
0914: Reservation event = appointment.getReservation();
0915: Allocatable allocatable = (Allocatable) resolve(new SimpleIdentifier(
0916: Allocatable.TYPE, resourceId));
0917: if (!event.hasAllocated(allocatable)) {
0918: event.addAllocatable(allocatable);
0919: }
0920: Appointment[] appointments = event.getRestriction(allocatable);
0921: Appointment[] newAppointments = new Appointment[appointments.length + 1];
0922: System.arraycopy(appointments, 0, newAppointments, 0,
0923: appointments.length);
0924: newAppointments[appointments.length] = appointment;
0925: if (event.getAppointments().length > newAppointments.length) {
0926: event.setRestriction(allocatable, newAppointments);
0927: } else {
0928: event.setRestriction(allocatable, new Appointment[] {});
0929: }
0930: }
0931:
0932: public void delete(RefEntity entity) throws SQLException {
0933: int appointmentId = getId(entity);
0934: executeBatchedStatement(con, "DELETE FROM " + tableName
0935: + " WHERE APPOINTMENT_ID = " + appointmentId);
0936: }
0937:
0938: }
0939:
0940: class AppointmentExceptionStorage extends EntityStorage {
0941: public AppointmentExceptionStorage(RaplaContext context)
0942: throws RaplaException {
0943: super (context, "APPOINTMENT_EXCEPTION", new String[] {
0944: "APPOINTMENT_ID", "EXCEPTION_DATE" });
0945: }
0946:
0947: protected void write(PreparedStatement stmt, RefEntity entity)
0948: throws SQLException, RaplaException {
0949: int appointmentId = getId(entity);
0950: Appointment appointment = (Appointment) entity;
0951: Repeating repeating = appointment.getRepeating();
0952: if (repeating == null) {
0953: return;
0954: }
0955: Date[] exceptions = repeating.getExceptions();
0956: for (int i = 0; i < exceptions.length; i++) {
0957: java.sql.Timestamp exception = new java.sql.Timestamp(
0958: exceptions[i].getTime());
0959: stmt.setInt(1, appointmentId);
0960: stmt.setTimestamp(2, exception);
0961: stmt.executeUpdate();
0962: }
0963: }
0964:
0965: protected void load(ResultSet rset) throws SQLException,
0966: RaplaException {
0967: int appointmentId = rset.getInt(1);
0968: Appointment appointment;
0969: try {
0970: appointment = (Appointment) resolve(new SimpleIdentifier(
0971: Appointment.TYPE, appointmentId));
0972: } catch (EntityNotFoundException ex) {
0973: getLogger()
0974: .warn(
0975: "Could not find appointment with id "
0976: + appointmentId
0977: + " for the specified exception. Ignoring.");
0978: return;
0979: }
0980:
0981: Repeating repeating = appointment.getRepeating();
0982: if (repeating != null) {
0983: Date date = new Date(rset.getDate(2).getTime());
0984: repeating.addException(date);
0985: }
0986: }
0987:
0988: public void delete(RefEntity entity) throws SQLException {
0989: int appointmentId = getId(entity);
0990: executeBatchedStatement(con, "DELETE FROM " + tableName
0991: + " WHERE APPOINTMENT_ID = " + appointmentId);
0992: }
0993:
0994: }
0995:
0996: class DynamicTypeStorage extends RaplaTypeStorage {
0997:
0998: public DynamicTypeStorage(RaplaContext context)
0999: throws RaplaException {
1000: super (context, DynamicType.TYPE, "DYNAMIC_TYPE", new String[] {
1001: "ID", "TYPE_KEY", "DEFINITION" });
1002: }
1003:
1004: protected void write(PreparedStatement stmt, RefEntity entity)
1005: throws SQLException, RaplaException {
1006: stmt.setInt(1, getId(entity));
1007: DynamicType type = (DynamicType) entity;
1008: stmt.setString(2, type.getElementKey());
1009: stmt.setString(3, getXML(type));
1010: stmt.executeUpdate();
1011: }
1012:
1013: protected void load(ResultSet rset) throws SQLException,
1014: RaplaException {
1015: String xml = getString(rset, 3);
1016: processXML(DynamicType.TYPE, xml);
1017: }
1018:
1019: }
1020:
1021: class PreferenceStorage extends RaplaTypeStorage {
1022:
1023: public PreferenceStorage(RaplaContext context)
1024: throws RaplaException {
1025: super (context, Preferences.TYPE, "PREFERENCE", new String[] {
1026: "USER_ID", "ROLE", "STRING_VALUE", "XML_VALUE" });
1027: }
1028:
1029: protected void write(PreparedStatement stmt, RefEntity entity)
1030: throws SQLException, RaplaException {
1031: PreferencesImpl preferences = (PreferencesImpl) entity;
1032: User user = (User) preferences.getOwner();
1033: if (user == null) {
1034: stmt.setObject(1, null);
1035: } else {
1036: stmt.setInt(1, getId((RefEntity) user));
1037: }
1038: Iterator it = preferences.getPreferenceEntries();
1039: while (it.hasNext()) {
1040: String role = (String) it.next();
1041: Object entry = preferences.getEntry(role);
1042: stmt.setString(2, role);
1043: if (entry instanceof String) {
1044: stmt.setString(3, (String) entry);
1045: stmt.setString(4, null);
1046: } else {
1047: //System.out.println("Role " + role + " CHILDREN " + conf.getChildren().length);
1048: String xml = getXML((RaplaObject) entry);
1049: stmt.setString(3, null);
1050: stmt.setString(4, xml);
1051: }
1052: stmt.executeUpdate();
1053: }
1054: }
1055:
1056: public void save(RefEntity entity) throws SQLException,
1057: RaplaException {
1058: delete(entity);
1059: insert(entity);
1060: }
1061:
1062: protected void load(ResultSet rset) throws SQLException,
1063: RaplaException {
1064: //findPreferences
1065: //check if value set
1066: // yes read value
1067: // no read xml
1068:
1069: int userIdAsInt = rset.getInt(1);
1070: User owner = null;
1071: Object preferenceId;
1072: if (!rset.wasNull()) {
1073: Object userId = new SimpleIdentifier(User.TYPE, userIdAsInt);
1074: owner = (User) get(userId);
1075: preferenceId = new SimpleIdentifier(Preferences.TYPE,
1076: userIdAsInt);
1077: } else {
1078: preferenceId = new SimpleIdentifier(Preferences.TYPE, 0);
1079: }
1080: PreferencesImpl preferences = (PreferencesImpl) get(preferenceId);
1081: if (preferences == null) {
1082: preferences = new PreferencesImpl();
1083: preferences.setId(preferenceId);
1084: preferences.setOwner(owner);
1085: put(preferences);
1086: }
1087: String configRole = getString(rset, 2);
1088: String value = rset.getString(3);
1089: if (!rset.wasNull()) {
1090: preferences.putEntry(configRole, value);
1091: } else {
1092: String xml = rset.getString(4);
1093:
1094: PreferenceReader contentHandler = (PreferenceReader) processXML(
1095: Preferences.TYPE, xml);
1096: try {
1097: RaplaObject type = contentHandler.getChildType();
1098: preferences.putEntry(configRole, type);
1099: } catch (SAXException ex) {
1100: throw new RaplaException(ex);
1101: }
1102: }
1103: }
1104:
1105: public void delete(RefEntity entity) throws SQLException {
1106: PreferencesImpl preferences = (PreferencesImpl) entity;
1107: User user = (User) preferences.getOwner();
1108: if (user != null) {
1109: int userId = getId((RefEntity) user);
1110: executeBatchedStatement(con, "DELETE FROM " + tableName
1111: + " WHERE USER_ID = " + userId);
1112: } else {
1113: executeBatchedStatement(con, "DELETE FROM " + tableName
1114: + " WHERE USER_ID = null");
1115: }
1116: }
1117:
1118: }
1119:
1120: class UserStorage extends RaplaTypeStorage {
1121: UserGroupStorage groupStorage;
1122:
1123: public UserStorage(RaplaContext context) throws RaplaException {
1124: super (context, User.TYPE, "RAPLA_USER", new String[] { "ID",
1125: "USERNAME", "PASSWORD", "NAME", "EMAIL", "ISADMIN" });
1126: groupStorage = new UserGroupStorage(context);
1127: addSubStorage(groupStorage);
1128: }
1129:
1130: protected void write(PreparedStatement stmt, RefEntity entity)
1131: throws SQLException, RaplaException {
1132: User user = (User) entity;
1133: if (getLogger().isDebugEnabled())
1134: getLogger().debug("Inserting User " + user.getUsername());
1135: stmt.setInt(1, getId(entity));
1136: stmt.setString(2, user.getUsername());
1137: String password = cache.getPassword(entity.getId());
1138: stmt.setString(3, password);
1139: stmt.setString(4, user.getName());
1140: stmt.setString(5, user.getEmail());
1141: stmt.setInt(6, user.isAdmin() ? 1 : 0);
1142: stmt.executeUpdate();
1143: }
1144:
1145: protected void load(ResultSet rset) throws SQLException,
1146: RaplaException {
1147: int idAsInt = rset.getInt(1);
1148: String username = getString(rset, 2);
1149: String name = getString(rset, 4);
1150: String email = getString(rset, 5);
1151: boolean isAdmin = rset.getInt(6) == 1;
1152: UserImpl user = new UserImpl();
1153: Object userId = new SimpleIdentifier(User.TYPE, idAsInt);
1154: user.setId(userId);
1155: user.setUsername(username);
1156: user.setName(name);
1157: user.setEmail(email);
1158: user.setAdmin(isAdmin);
1159: String password = getString(rset, 3);
1160: if (!rset.wasNull()) {
1161: putPassword(userId, password);
1162: }
1163: put(user);
1164: }
1165:
1166: }
1167:
1168: class UserGroupStorage extends EntityStorage {
1169: public UserGroupStorage(RaplaContext context) throws RaplaException {
1170: super (context, "RAPLA_USER_GROUP", new String[] { "USER_ID",
1171: "CATEGORY_ID" });
1172: }
1173:
1174: public void save(RefEntity entity) throws SQLException,
1175: RaplaException {
1176: delete(entity);
1177: insert(entity);
1178: }
1179:
1180: protected void write(PreparedStatement stmt, RefEntity entity)
1181: throws SQLException, RaplaException {
1182: int userId = getId(entity);
1183: User user = (User) entity;
1184: stmt.setInt(1, userId);
1185: Category[] categories = user.getGroups();
1186: for (int i = 0; i < categories.length; i++) {
1187: stmt.setInt(2, getId((RefEntity) categories[i]));
1188: stmt.executeUpdate();
1189: }
1190: }
1191:
1192: protected void load(ResultSet rset) throws SQLException,
1193: RaplaException {
1194: int userId = rset.getInt(1);
1195: int categoryId = rset.getInt(2);
1196: User user = (User) resolve(new SimpleIdentifier(User.TYPE,
1197: userId));
1198: Category category = (Category) resolve(new SimpleIdentifier(
1199: Category.TYPE, categoryId));
1200: user.addGroup(category);
1201: }
1202:
1203: public void delete(RefEntity entity) throws SQLException {
1204: int userId = getId(entity);
1205: executeBatchedStatement(con, "DELETE FROM " + tableName
1206: + " WHERE USER_ID = " + userId);
1207: }
1208: }
|