0001: /* Copyright 2002 The JA-SIG Collaborative. All rights reserved.
0002: * See license distributed with this file and
0003: * available online at http://www.uportal.org/license.html
0004: */
0005:
0006: package org.jasig.portal.layout.alm;
0007:
0008: import java.sql.Connection;
0009: import java.sql.PreparedStatement;
0010: import java.sql.ResultSet;
0011: import java.sql.SQLException;
0012: import java.sql.Statement;
0013: import java.sql.Timestamp;
0014: import java.sql.Types;
0015: import java.util.ArrayList;
0016: import java.util.Collections;
0017: import java.util.Date;
0018: import java.util.Enumeration;
0019: import java.util.HashMap;
0020: import java.util.Hashtable;
0021: import java.util.HashSet;
0022: import java.util.Set;
0023: import java.util.Map;
0024: import java.util.Iterator;
0025: import java.util.Collection;
0026: import java.util.List;
0027: import java.util.Vector;
0028:
0029: import org.jasig.portal.ChannelDefinition;
0030: import org.jasig.portal.ChannelParameter;
0031: import org.jasig.portal.EntityIdentifier;
0032: import org.jasig.portal.PortalException;
0033: import org.jasig.portal.RDBMServices;
0034: import org.jasig.portal.StructureStylesheetUserPreferences;
0035: import org.jasig.portal.ThemeStylesheetUserPreferences;
0036: import org.jasig.portal.ThemeStylesheetDescription;
0037: import org.jasig.portal.StructureStylesheetDescription;
0038: import org.jasig.portal.UserPreferences;
0039: import org.jasig.portal.UserProfile;
0040: import org.jasig.portal.channels.error.CError;
0041: import org.jasig.portal.channels.error.ErrorCode;
0042: import org.jasig.portal.groups.IEntityGroup;
0043: import org.jasig.portal.groups.IGroupMember;
0044: import org.jasig.portal.layout.node.IUserLayoutNodeDescription;
0045: import org.jasig.portal.layout.node.UserLayoutFolderDescription;
0046: import org.jasig.portal.layout.restrictions.IUserLayoutRestriction;
0047: import org.jasig.portal.layout.restrictions.UserLayoutRestrictionFactory;
0048: import org.jasig.portal.layout.restrictions.alm.PriorityRestriction;
0049: import org.jasig.portal.layout.simple.RDBMUserLayoutStore;
0050: import org.jasig.portal.rdbm.DatabaseMetaDataImpl;
0051: import org.jasig.portal.rdbm.IDatabaseMetadata;
0052: import org.jasig.portal.security.IPerson;
0053: import org.jasig.portal.services.GroupService;
0054: import org.jasig.portal.utils.CommonUtils;
0055:
0056: /**
0057: * AggregatedUserLayoutStore implementation using the relational database with SQL 92.
0058: * <p>
0059: * Company: Instructional Media & Magic
0060: *
0061: * Prior to uPortal 2.5, this class existed in the package org.jasig.portal.layout.
0062: * It was moved to its present package to reflect that it is part of Aggregated
0063: * Layouts.
0064: *
0065: * @author <a href="mailto:mvi@immagic.com">Michael Ivanov</a>
0066: * @version $Revision: 42045 $
0067: */
0068:
0069: public class AggregatedUserLayoutStore extends RDBMUserLayoutStore
0070: implements IAggregatedUserLayoutStore {
0071:
0072: private final ALFragmentNodeAttributeService nodeAttributeService = new ALFragmentNodeAttributeService(
0073: RDBMServices.getDataSource());
0074:
0075: private static final int LOST_FOLDER_ID = -1;
0076: private static final String NODE_SEPARATOR = "_";
0077:
0078: protected static final String FRAGMENT_UPDATE_SQL = "UPDATE UP_FRAGMENTS SET NEXT_NODE_ID=?,PREV_NODE_ID=?,CHLD_NODE_ID=?,PRNT_NODE_ID=?,"
0079: + "EXTERNAL_ID=?,CHAN_ID=?,NAME=?,TYPE=?,HIDDEN=?,IMMUTABLE=?,UNREMOVABLE=?,GROUP_KEY=?,"
0080: + "PRIORITY=? WHERE FRAGMENT_ID=? AND NODE_ID=?";
0081: protected static final String LAYOUT_UPDATE_SQL = "UPDATE UP_LAYOUT_STRUCT_AGGR SET NEXT_NODE_ID=?,PREV_NODE_ID=?,CHLD_NODE_ID=?,PRNT_NODE_ID=?,"
0082: + "EXTERNAL_ID=?,CHAN_ID=?,NAME=?,TYPE=?,HIDDEN=?,IMMUTABLE=?,UNREMOVABLE=?,GROUP_KEY=?,"
0083: + "PRIORITY=?,FRAGMENT_ID=?,FRAGMENT_NODE_ID=? WHERE LAYOUT_ID=? AND USER_ID=? AND NODE_ID=?";
0084: protected static final String FRAGMENT_RESTRICTION_UPDATE_SQL = "UPDATE UP_FRAGMENT_RESTRICTIONS SET RESTRICTION_VALUE=?"
0085: + " WHERE FRAGMENT_ID=? AND NODE_ID=? AND RESTRICTION_NAME=? AND RESTRICTION_TREE_PATH=?";
0086: protected static final String LAYOUT_RESTRICTION_UPDATE_SQL = "UPDATE UP_LAYOUT_RESTRICTIONS SET RESTRICTION_VALUE=?"
0087: + " WHERE LAYOUT_ID=? AND USER_ID=? AND NODE_ID=? AND RESTRICTION_NAME=? AND RESTRICTION_TREE_PATH=?";
0088: protected static final String CHANNEL_PARAM_UPDATE_SQL = "UPDATE UP_CHANNEL_PARAM SET CHAN_PARM_DESC=?,CHAN_PARM_VAL=?,CHAN_PARM_OVRD=?"
0089: + " WHERE CHAN_ID=? AND CHAN_PARM_NM=?";
0090: protected static final String CHANNEL_UPDATE_SQL = "UPDATE UP_CHANNEL SET CHAN_TITLE=?,CHAN_NAME=?,CHAN_DESC=?,CHAN_CLASS=?,CHAN_TYPE_ID=?,"
0091: + "CHAN_PUBL_ID=?,CHAN_PUBL_DT=?,CHAN_APVL_ID=?,CHAN_APVL_DT=?,CHAN_TIMEOUT=?,CHAN_EDITABLE=?,CHAN_HAS_HELP=?,CHAN_HAS_ABOUT=?,"
0092: + "CHAN_FNAME=?,CHAN_SECURE=? WHERE CHAN_ID=?";
0093: protected static final String FRAGMENT_ADD_SQL = "INSERT INTO UP_FRAGMENTS (FRAGMENT_ID,NODE_ID,NEXT_NODE_ID,PREV_NODE_ID,CHLD_NODE_ID,PRNT_NODE_ID,"
0094: + "EXTERNAL_ID,CHAN_ID,NAME,TYPE,HIDDEN,IMMUTABLE,UNREMOVABLE,GROUP_KEY,PRIORITY)"
0095: + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
0096: protected static final String LAYOUT_ADD_SQL = "INSERT INTO UP_LAYOUT_STRUCT_AGGR (LAYOUT_ID,USER_ID,NODE_ID,NEXT_NODE_ID,PREV_NODE_ID,CHLD_NODE_ID,PRNT_NODE_ID,"
0097: + "EXTERNAL_ID,CHAN_ID,NAME,TYPE,HIDDEN,IMMUTABLE,UNREMOVABLE,GROUP_KEY,PRIORITY,FRAGMENT_ID,FRAGMENT_NODE_ID)"
0098: + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
0099: protected static final String FRAGMENT_RESTRICTION_ADD_SQL = "INSERT INTO UP_FRAGMENT_RESTRICTIONS (RESTRICTION_NAME,NODE_ID,FRAGMENT_ID,RESTRICTION_VALUE,RESTRICTION_TREE_PATH)"
0100: + " VALUES (?,?,?,?,?)";
0101: protected static final String LAYOUT_RESTRICTION_ADD_SQL = "INSERT INTO UP_LAYOUT_RESTRICTIONS (RESTRICTION_NAME,LAYOUT_ID,USER_ID,NODE_ID,RESTRICTION_VALUE,RESTRICTION_TREE_PATH)"
0102: + " VALUES (?,?,?,?,?,?)";
0103: protected static final String CHANNEL_PARAM_ADD_SQL = "INSERT INTO UP_CHANNEL_PARAM (CHAN_ID,CHAN_PARM_NM,CHAN_PARM_DESC,CHAN_PARM_VAL,CHAN_PARM_OVRD)"
0104: + " VALUES (?,?,?,?,?)";
0105: protected static final String CHANNEL_ADD_SQL = "INSERT INTO UP_CHANNEL (CHAN_ID,CHAN_TITLE,CHAN_NAME,CHAN_DESC,CHAN_CLASS,CHAN_TYPE_ID,CHAN_PUBL_ID,"
0106: + "CHAN_PUBL_DT,CHAN_APVL_ID,CHAN_APVL_DT,CHAN_TIMEOUT,CHAN_EDITABLE,CHAN_HAS_HELP,CHAN_HAS_ABOUT,"
0107: + "CHAN_FNAME,CHAN_SECURE) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
0108:
0109: private Object fragmentLock = new Object();
0110:
0111: public AggregatedUserLayoutStore() throws Exception {
0112: super ();
0113: }
0114:
0115: /**
0116: * Return the Structure ID tag (Overloaded)
0117: * @param structId
0118: * @param chanId
0119: * @return ID tag
0120: */
0121: protected String getStructId(int structId, int chanId) {
0122: return structId + "";
0123: }
0124:
0125: public void setStructureStylesheetUserPreferences(IPerson person,
0126: int profileId, StructureStylesheetUserPreferences ssup)
0127: throws Exception {
0128: int userId = person.getID();
0129: Connection con = null;
0130: try {
0131: con = RDBMServices.getConnection();
0132: // Set autocommit false for the connection
0133: int stylesheetId = ssup.getStylesheetId();
0134: RDBMServices.setAutoCommit(con, false);
0135:
0136: // write out params
0137: for (Enumeration e = ssup.getParameterValues().keys(); e
0138: .hasMoreElements();) {
0139: String pName = (String) e.nextElement();
0140: // see if the parameter was already there
0141: PreparedStatement selectStmt = null;
0142: try {
0143: final String sQuery = "SELECT PARAM_VAL FROM UP_SS_USER_PARM WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=1 AND PARAM_NAME=?";
0144: selectStmt = con.prepareStatement(sQuery);
0145: selectStmt.setInt(1, userId);
0146: selectStmt.setInt(2, profileId);
0147: selectStmt.setInt(3, stylesheetId);
0148: selectStmt.setString(4, pName);
0149: if (log.isDebugEnabled())
0150: log
0151: .debug("AggregatedUserLayoutStore::setStructureStylesheetUserPreferences(): "
0152: + sQuery);
0153: ResultSet rs = null;
0154: try {
0155: rs = selectStmt.executeQuery();
0156: String query = null;
0157: if (rs.next()) {
0158: // update
0159: query = "UPDATE UP_SS_USER_PARM SET PARAM_VAL=? WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=? AND PARAM_NAME=?";
0160: } else {
0161: // insert
0162: query = "INSERT INTO UP_SS_USER_PARM (PARAM_VAL,USER_ID,PROFILE_ID,SS_ID,SS_TYPE,PARAM_NAME) VALUES (?,?,?,?,?,?)";
0163: }
0164: PreparedStatement insertStmt = null;
0165: try {
0166: insertStmt = con.prepareStatement(query);
0167: insertStmt.setString(1, ssup
0168: .getParameterValue(pName));
0169: insertStmt.setInt(2, userId);
0170: insertStmt.setInt(3, profileId);
0171: insertStmt.setInt(4, stylesheetId);
0172: insertStmt.setInt(5, 1);
0173: insertStmt.setString(6, pName);
0174: if (log.isDebugEnabled())
0175: log
0176: .debug("AggregatedUserLayoutStore::setStructureStylesheetUserPreferences(): "
0177: + query);
0178: insertStmt.executeUpdate();
0179: } finally {
0180: try {
0181: insertStmt.close();
0182: } catch (Exception ee) {
0183: }
0184: }
0185: } finally {
0186: try {
0187: rs.close();
0188: } catch (Exception ee) {
0189: }
0190: }
0191: } finally {
0192: try {
0193: selectStmt.close();
0194: } catch (Exception ee) {
0195: }
0196: }
0197: }
0198:
0199: final String _sQuery = "SELECT PARAM_VAL FROM UP_SS_USER_ATTS WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=1 AND STRUCT_ID=? AND PARAM_NAME=? AND PARAM_TYPE=2";
0200: final String _sUpdateQuery = "UPDATE UP_SS_USER_ATTS SET PARAM_VAL=? WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=1 AND STRUCT_ID=? AND PARAM_NAME=? AND PARAM_TYPE=2";
0201: final String _sInsertQuery = "INSERT INTO UP_SS_USER_ATTS (USER_ID,PROFILE_ID,SS_ID,SS_TYPE,STRUCT_ID,PARAM_NAME,PARAM_TYPE,PARAM_VAL) VALUES (?,?,?,1,?,?,2,?)";
0202: // write out folder attributes
0203: for (Enumeration e = ssup.getFolders(); e.hasMoreElements();) {
0204: String folderId = (String) e.nextElement();
0205: for (Enumeration attre = ssup.getFolderAttributeNames(); attre
0206: .hasMoreElements();) {
0207: String pName = (String) attre.nextElement();
0208: String pValue = ssup
0209: .getDefinedFolderAttributeValue(folderId,
0210: pName);
0211: if (pValue != null) {
0212:
0213: PreparedStatement selectStmt = null;
0214: try {
0215: selectStmt = con.prepareStatement(_sQuery);
0216: selectStmt.setInt(1, userId);
0217: selectStmt.setInt(2, profileId);
0218: selectStmt.setInt(3, stylesheetId);
0219: selectStmt.setInt(4, new Integer(folderId)
0220: .intValue());
0221: selectStmt.setString(5, pName);
0222: if (log.isDebugEnabled())
0223: log
0224: .debug("AggregatedUserLayoutStore::setStructureStylesheetUserPreferences(): "
0225: + _sQuery);
0226: ResultSet rs = null;
0227: try {
0228: rs = selectStmt.executeQuery();
0229: if (rs.next()) {
0230: // update
0231: PreparedStatement updateStmt = null;
0232: try {
0233: updateStmt = con
0234: .prepareStatement(_sUpdateQuery);
0235: updateStmt.setString(1, pValue);
0236: updateStmt.setInt(2, userId);
0237: updateStmt.setInt(3, profileId);
0238: updateStmt.setInt(4,
0239: stylesheetId);
0240: updateStmt.setInt(5,
0241: new Integer(folderId)
0242: .intValue());
0243: updateStmt.setString(6, pName);
0244: if (log.isDebugEnabled())
0245: log
0246: .debug("AggregatedUserLayoutStore::setStructureStylesheetUserPreferences(): "
0247: + _sUpdateQuery);
0248: updateStmt.executeUpdate();
0249: } finally {
0250: try {
0251: updateStmt.close();
0252: } catch (Exception ee) {
0253: }
0254: }
0255: } else {
0256: // insert
0257: PreparedStatement insertStmt = null;
0258: try {
0259: insertStmt = con
0260: .prepareStatement(_sInsertQuery);
0261: insertStmt.setInt(1, userId);
0262: insertStmt.setInt(2, profileId);
0263: insertStmt.setInt(3,
0264: stylesheetId);
0265: insertStmt.setInt(4,
0266: new Integer(folderId)
0267: .intValue());
0268: insertStmt.setString(5, pName);
0269: insertStmt.setString(6, pValue);
0270: if (log.isDebugEnabled())
0271: log
0272: .debug("AggregatedUserLayoutStore::setStructureStylesheetUserPreferences(): "
0273: + _sInsertQuery);
0274: insertStmt.executeUpdate();
0275: } finally {
0276: try {
0277: insertStmt.close();
0278: } catch (Exception ee) {
0279: }
0280: }
0281: }
0282: } finally {
0283: try {
0284: rs.close();
0285: } catch (Exception ee) {
0286: }
0287: }
0288: } finally {
0289: try {
0290: selectStmt.close();
0291: } catch (Exception ee) {
0292: }
0293: }
0294: }
0295: }
0296: }
0297: // store user preferences
0298: final String _chanQuery = "SELECT PARAM_VAL FROM UP_SS_USER_ATTS WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=1 AND STRUCT_ID=? AND PARAM_NAME=? AND PARAM_TYPE=3";
0299: final String _chanUpdateQuery = "UPDATE UP_SS_USER_ATTS SET PARAM_VAL=? WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=1 AND STRUCT_ID=? AND PARAM_NAME=? AND PARAM_TYPE=3";
0300: final String _chanInsertQuery = "INSERT INTO UP_SS_USER_ATTS (USER_ID,PROFILE_ID,SS_ID,SS_TYPE,STRUCT_ID,PARAM_NAME,PARAM_TYPE,PARAM_VAL) VALUES (?,?,?,1,?,?,3,?)";
0301: // write out channel attributes
0302: for (Enumeration e = ssup.getChannels(); e
0303: .hasMoreElements();) {
0304: String channelId = (String) e.nextElement();
0305: for (Enumeration attre = ssup
0306: .getChannelAttributeNames(); attre
0307: .hasMoreElements();) {
0308: String pName = (String) attre.nextElement();
0309: String pValue = ssup
0310: .getDefinedChannelAttributeValue(channelId,
0311: pName);
0312: if (pValue != null) {
0313: PreparedStatement selectStmt = null;
0314: try {
0315: selectStmt = con
0316: .prepareStatement(_chanQuery);
0317: selectStmt.setInt(1, userId);
0318: selectStmt.setInt(2, profileId);
0319: selectStmt.setInt(3, stylesheetId);
0320: selectStmt.setInt(4, new Integer(channelId)
0321: .intValue());
0322: selectStmt.setString(5, pName);
0323: if (log.isDebugEnabled())
0324: log
0325: .debug("AggregatedUserLayoutStore::setStructureStylesheetUserPreferences(): "
0326: + _chanQuery);
0327: ResultSet rs = null;
0328: try {
0329: rs = selectStmt.executeQuery();
0330: if (rs.next()) {
0331: // update
0332: PreparedStatement updateStmt = null;
0333: try {
0334: updateStmt = con
0335: .prepareStatement(_chanUpdateQuery);
0336: updateStmt.setString(1, pValue);
0337: updateStmt.setInt(2, userId);
0338: updateStmt.setInt(3, profileId);
0339: updateStmt.setInt(4,
0340: stylesheetId);
0341: updateStmt.setInt(5,
0342: new Integer(channelId)
0343: .intValue());
0344: updateStmt.setString(6, pName);
0345: if (log.isDebugEnabled())
0346: log
0347: .debug("AggregatedUserLayoutStore::setStructureStylesheetUserPreferences(): "
0348: + _chanUpdateQuery);
0349: updateStmt.executeUpdate();
0350: } finally {
0351: try {
0352: updateStmt.close();
0353: } catch (Exception ee) {
0354: }
0355: }
0356: } else {
0357: // insert
0358: PreparedStatement insertStmt = null;
0359: try {
0360: insertStmt = con
0361: .prepareStatement(_chanInsertQuery);
0362: insertStmt.setInt(1, userId);
0363: insertStmt.setInt(2, profileId);
0364: insertStmt.setInt(3,
0365: stylesheetId);
0366: insertStmt.setInt(4,
0367: new Integer(channelId)
0368: .intValue());
0369: insertStmt.setString(5, pName);
0370: insertStmt.setString(6, pValue);
0371: if (log.isDebugEnabled())
0372: log
0373: .debug("AggregatedUserLayoutStore::setStructureStylesheetUserPreferences(): "
0374: + _chanInsertQuery);
0375: insertStmt.executeUpdate();
0376: } finally {
0377: try {
0378: insertStmt.close();
0379: } catch (Exception ee) {
0380: }
0381: }
0382: }
0383: } finally {
0384: try {
0385: rs.close();
0386: } catch (Exception ee) {
0387: }
0388: }
0389: } finally {
0390: try {
0391: selectStmt.close();
0392: } catch (Exception ee) {
0393: }
0394: }
0395: }
0396: }
0397: }
0398: RDBMServices.commit(con);
0399: } catch (Exception e) {
0400: // Roll back the transaction
0401: RDBMServices.rollback(con);
0402: throw e;
0403: } finally {
0404: RDBMServices.releaseConnection(con);
0405: }
0406: }
0407:
0408: public void setThemeStylesheetUserPreferences(IPerson person,
0409: int profileId, ThemeStylesheetUserPreferences tsup)
0410: throws Exception {
0411: int userId = person.getID();
0412: Connection con = null;
0413: try {
0414: con = RDBMServices.getConnection();
0415: int stylesheetId = tsup.getStylesheetId();
0416: // Set autocommit false for the connection
0417: RDBMServices.setAutoCommit(con, false);
0418: // write out params
0419: final String sQuery = "SELECT PARAM_VAL FROM UP_SS_USER_PARM WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=2 AND PARAM_NAME=?";
0420: final String sUpdateQuery = "UPDATE UP_SS_USER_PARM SET PARAM_VAL=? WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=2 AND PARAM_NAME=?";
0421: final String sInsertQuery = "INSERT INTO UP_SS_USER_PARM (USER_ID,PROFILE_ID,SS_ID,SS_TYPE,PARAM_NAME,PARAM_VAL) VALUES (?,?,?,?,?,?)";
0422:
0423: for (Enumeration e = tsup.getParameterValues().keys(); e
0424: .hasMoreElements();) {
0425: String pName = (String) e.nextElement();
0426: PreparedStatement selectStmt = null;
0427: try {
0428: // see if the parameter was already there
0429: // fix for escaping column entries
0430: selectStmt = con.prepareStatement(sQuery);
0431: selectStmt.setInt(1, userId);
0432: selectStmt.setInt(2, profileId);
0433: selectStmt.setInt(3, stylesheetId);
0434: selectStmt.setString(4, pName);
0435: if (log.isDebugEnabled())
0436: log
0437: .debug("AggregatedUserLayoutStore::setThemeStylesheetUserPreferences(): "
0438: + sQuery);
0439: ResultSet rs = null;
0440: try {
0441: rs = selectStmt.executeQuery();
0442: if (rs.next()) {
0443: PreparedStatement updateStmt = null;
0444: try {
0445: updateStmt = con
0446: .prepareStatement(sUpdateQuery);
0447: updateStmt.setString(1, tsup
0448: .getParameterValue(pName));
0449: updateStmt.setInt(2, userId);
0450: updateStmt.setInt(3, profileId);
0451: updateStmt.setInt(4, stylesheetId);
0452: updateStmt.setString(5, pName);
0453: if (log.isDebugEnabled())
0454: log
0455: .debug("AggregatedUserLayoutStore::setThemeStylesheetUserPreferences(): "
0456: + sUpdateQuery);
0457: updateStmt.executeUpdate();
0458: } catch (Exception eex) {
0459: // should we throw exception or just simply allow for this one 2 fail and attempt the rest since these are just theme attributes?
0460: } finally {
0461: try {
0462: updateStmt.close();
0463: } catch (Exception ee) {
0464: }
0465: }
0466: } else {
0467: // insert
0468: // CSU Chico fix for escaping column entries
0469: // sQuery = "INSERT INTO UP_SS_USER_PARM (USER_ID,PROFILE_ID,SS_ID,SS_TYPE,PARAM_NAME,PARAM_VAL) VALUES (" + userId
0470: // + "," + profileId + "," + stylesheetId + ",2,'" + pName + "','" + tsup.getParameterValue(pName) + "')";
0471: PreparedStatement insertStmt = null;
0472: try {
0473: insertStmt = con
0474: .prepareStatement(sInsertQuery);
0475: insertStmt.setInt(1, userId);
0476: insertStmt.setInt(2, profileId);
0477: insertStmt.setInt(3, stylesheetId);
0478: insertStmt.setInt(4, 2);
0479: insertStmt.setString(5, pName);
0480: insertStmt.setString(6, tsup
0481: .getParameterValue(pName));
0482: if (log.isDebugEnabled())
0483: log
0484: .debug("AggregatedUserLayoutStore::setThemeStylesheetUserPreferences(): "
0485: + sInsertQuery);
0486: insertStmt.executeUpdate();
0487: } catch (Exception eex) {
0488: } finally {
0489: try {
0490: insertStmt.close();
0491: } catch (Exception ee) {
0492: }
0493: }
0494: }
0495: } finally {
0496: try {
0497: rs.close();
0498: } catch (Exception ee) {
0499: }
0500: }
0501: } finally {
0502: try {
0503: selectStmt.close();
0504: } catch (Exception ee) {
0505: }
0506: }
0507: }
0508:
0509: final String _sSelectQuery = "SELECT PARAM_VAL FROM UP_SS_USER_ATTS WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=2 AND STRUCT_ID=? AND PARAM_NAME=? AND PARAM_TYPE=3";
0510: final String _sUpdateQuery = "UPDATE UP_SS_USER_ATTS SET PARAM_VAL=? WHERE USER_ID=? AND PROFILE_ID=? AND SS_ID=? AND SS_TYPE=2 AND STRUCT_ID=? AND PARAM_NAME=? AND PARAM_TYPE=3";
0511: final String _sInsertQuery = "INSERT INTO UP_SS_USER_ATTS (USER_ID,PROFILE_ID,SS_ID,SS_TYPE,STRUCT_ID,PARAM_NAME,PARAM_TYPE,PARAM_VAL) VALUES (?,?,?,?,?,?,?,?)";
0512:
0513: // write out channel attributes
0514: for (Enumeration e = tsup.getChannels(); e
0515: .hasMoreElements();) {
0516: String channelId = (String) e.nextElement();
0517: for (Enumeration attre = tsup
0518: .getChannelAttributeNames(); attre
0519: .hasMoreElements();) {
0520: String pName = (String) attre.nextElement();
0521: String pValue = tsup
0522: .getDefinedChannelAttributeValue(channelId,
0523: pName);
0524: if (pValue != null) {
0525: // store user preferences
0526: PreparedStatement pssq = null;
0527: try {
0528: pssq = con.prepareStatement(_sSelectQuery);
0529: pssq.setInt(1, userId);
0530: pssq.setInt(2, profileId);
0531: pssq.setInt(3, stylesheetId);
0532: pssq.setInt(4, Integer.parseInt(channelId));
0533: pssq.setString(5, pName);
0534: if (log.isDebugEnabled())
0535: log
0536: .debug("AggregatedUserLayoutStore::setThemeStylesheetUserPreferences(): "
0537: + _sSelectQuery);
0538: ResultSet rs = null;
0539: try {
0540: rs = pssq.executeQuery();
0541: if (rs.next()) {
0542: // update
0543: PreparedStatement updateStmt = null;
0544: try {
0545: updateStmt = con
0546: .prepareStatement(_sUpdateQuery);
0547: updateStmt.setString(1, pValue);
0548: updateStmt.setInt(2, userId);
0549: updateStmt.setInt(3, profileId);
0550: updateStmt.setInt(4,
0551: stylesheetId);
0552: updateStmt.setInt(5, Integer
0553: .parseInt(channelId));
0554: updateStmt.setString(6, pName);
0555: if (log.isDebugEnabled())
0556: log
0557: .debug("AggregatedUserLayoutStore::setThemeStylesheetUserPreferences(): "
0558: + _sUpdateQuery);
0559: updateStmt.executeUpdate();
0560: } finally {
0561: try {
0562: updateStmt.close();
0563: } catch (Exception ee) {
0564: }
0565: }
0566: } else {
0567: // insert
0568: PreparedStatement insertStmt = null;
0569: try {
0570: insertStmt = con
0571: .prepareStatement(_sInsertQuery);
0572: insertStmt.setInt(1, userId);
0573: insertStmt.setInt(2, profileId);
0574: insertStmt.setInt(3,
0575: stylesheetId);
0576: insertStmt.setInt(4, 2);
0577: insertStmt.setInt(5, Integer
0578: .parseInt(channelId));
0579: insertStmt.setString(6, pName);
0580: insertStmt.setInt(7, 3);
0581: insertStmt.setString(8, pValue);
0582: if (log.isDebugEnabled())
0583: log
0584: .debug("AggregatedUserLayoutStore::setThemeStylesheetUserPreferences(): "
0585: + _sInsertQuery);
0586: insertStmt.executeUpdate();
0587: } finally {
0588: try {
0589: insertStmt.close();
0590: } catch (Exception ee) {
0591: }
0592: }
0593: }
0594: } finally {
0595: try {
0596: rs.close();
0597: } catch (Exception ee) {
0598: }
0599: }
0600: } catch (Exception eex) {
0601: throw eex;
0602: } finally {
0603: try {
0604: pssq.close();
0605: } catch (Exception ee) {
0606: }
0607: }
0608: }
0609: }
0610: }
0611: // Commit the transaction
0612: RDBMServices.commit(con);
0613: } catch (Exception e) {
0614: // Roll back the transaction
0615: RDBMServices.rollback(con);
0616: throw e;
0617: } finally {
0618: RDBMServices.releaseConnection(con);
0619: }
0620: }
0621:
0622: /**
0623: * Add the new user layout node.
0624: * @param person an <code>IPerson</code> object specifying the user
0625: * @param profile a user profile for which the layout is being stored
0626: * @param node a <code>ALNode</code> object specifying the node
0627: * @return a <code>ALNode</code> object specifying the node with the generated node ID
0628: * @exception PortalException if an error occurs
0629: */
0630: public synchronized ALNode addUserLayoutNode(IPerson person,
0631: UserProfile profile, ALNode node) throws PortalException {
0632:
0633: Connection con = null;
0634:
0635: try {
0636: // Retrieve our own connection
0637: con = RDBMServices.getConnection();
0638: RDBMServices.setAutoCommit(con, false);
0639:
0640: // Add the user layout node using the connection
0641: ALNode newNode = addUserLayoutNode(person, profile, node,
0642: con);
0643:
0644: // Commit all changes
0645: RDBMServices.commit(con);
0646:
0647: return newNode;
0648:
0649: } catch (Exception e) {
0650: e.printStackTrace();
0651: String errorMessage = e.getMessage();
0652: try {
0653: RDBMServices.rollback(con);
0654: } catch (SQLException sqle) {
0655: log.error(sqle.toString());
0656: errorMessage += ":" + sqle.getMessage();
0657: }
0658: throw new PortalException(errorMessage, e);
0659: } finally {
0660: try {
0661: if (con != null) {
0662: RDBMServices.setAutoCommit(con, true);
0663: RDBMServices.releaseConnection(con);
0664: }
0665: } catch (Exception e) {
0666: log
0667: .error("AggregatedUserLayoutStore::addUserLayoutNode(): Failed to clean up resources.");
0668: }
0669: }
0670: }
0671:
0672: /**
0673: * Add the new user layout node.
0674: * @param person an <code>IPerson</code> object specifying the user
0675: * @param profile a user profile for which the layout is being stored
0676: * @param node a <code>ALNode</code> object specifying the node
0677: * @param con The connection instance to be used to perform all database operations.
0678: * @return a <code>ALNode</code> object specifying the node with the generated node ID
0679: * @exception PortalException if an error occurs
0680: */
0681: private ALNode addUserLayoutNode(IPerson person,
0682: UserProfile profile, ALNode node, Connection con)
0683: throws PortalException {
0684:
0685: Statement stmt = null;
0686: ResultSet rs = null;
0687: PreparedStatement psAddNode = null;
0688: PreparedStatement psAddRestriction = null;
0689:
0690: try {
0691:
0692: int nodeId = 0;
0693: int layoutId = -1;
0694: int userId = person.getID();
0695: IALNodeDescription nodeDesc = (IALNodeDescription) node
0696: .getNodeDescription();
0697: int assignedNodeId = CommonUtils.parseInt(nodeDesc.getId());
0698: int fragmentId = CommonUtils.parseInt(nodeDesc
0699: .getFragmentId());
0700: int fragmentNodeId = CommonUtils.parseInt(nodeDesc
0701: .getFragmentNodeId());
0702:
0703: boolean nodeIdAssigned = false;
0704:
0705: stmt = con.createStatement();
0706:
0707: // If a valid Id was assigned for this node use that one instead
0708: if (assignedNodeId > 0) {
0709: nodeId = assignedNodeId;
0710: nodeIdAssigned = true;
0711: }
0712:
0713: // eventually, we need to fix template layout implementations so you can just do this:
0714: // int layoutId=profile.getLayoutId();
0715: // but for now:
0716: if (fragmentId > 0 && fragmentNodeId <= 0) {
0717:
0718: // Assigned a new node Id only if a valid one was not already assigned
0719: if (!nodeIdAssigned) {
0720: // TO GET THE NEXT NODE ID FOR FRAGMENT NODES
0721: rs = stmt
0722: .executeQuery("SELECT MAX(NODE_ID) FROM UP_FRAGMENTS WHERE FRAGMENT_ID="
0723: + fragmentId);
0724: if (rs.next())
0725: nodeId = rs.getInt(1) + 1;
0726: else
0727: nodeId = 1;
0728:
0729: rs.close();
0730: rs = null;
0731: }
0732:
0733: } else {
0734: String subSelectString = "SELECT LAYOUT_ID FROM UP_USER_PROFILE WHERE USER_ID="
0735: + userId
0736: + " AND PROFILE_ID="
0737: + profile.getProfileId();
0738: log
0739: .debug("AggregatedUserLayoutStore::addUserLayoutNode(): "
0740: + subSelectString);
0741: rs = stmt.executeQuery(subSelectString);
0742: try {
0743: if (rs.next())
0744: layoutId = rs.getInt(1);
0745: } finally {
0746: rs.close();
0747: rs = null;
0748: }
0749:
0750: // Only update next struct_id if a new node id was created- no valid node id was assigned
0751: if (!nodeIdAssigned) {
0752:
0753: // Make sure the next struct id is set in case the user adds a channel
0754: String sQuery = "SELECT NEXT_STRUCT_ID FROM UP_USER WHERE USER_ID="
0755: + userId;
0756: log
0757: .debug("AggregatedUserLayoutStore::addUserLayoutNode(): "
0758: + sQuery);
0759:
0760: rs = stmt.executeQuery(sQuery);
0761: try {
0762: if (rs.next())
0763: ;
0764: nodeId = rs.getInt(1) + 1;
0765: } finally {
0766: rs.close();
0767: rs = null;
0768: }
0769:
0770: sQuery = "UPDATE UP_USER SET NEXT_STRUCT_ID="
0771: + nodeId + " WHERE USER_ID=" + userId;
0772: stmt.executeUpdate(sQuery);
0773: }
0774: }
0775:
0776: // Setting the node ID
0777: nodeDesc.setId(nodeId + "");
0778:
0779: if (fragmentId > 0 && fragmentNodeId <= 0)
0780: psAddNode = con.prepareStatement(FRAGMENT_ADD_SQL);
0781: else
0782: psAddNode = con.prepareStatement(LAYOUT_ADD_SQL);
0783:
0784: if (fragmentId > 0)
0785: psAddRestriction = con
0786: .prepareStatement(FRAGMENT_RESTRICTION_ADD_SQL);
0787: else
0788: psAddRestriction = con
0789: .prepareStatement(LAYOUT_RESTRICTION_ADD_SQL);
0790:
0791: if (node.getNodeType() == IUserLayoutNodeDescription.CHANNEL) {
0792: IALChannelDescription channelDesc = (IALChannelDescription) nodeDesc;
0793: int publishId = CommonUtils.parseInt(channelDesc
0794: .getChannelPublishId());
0795: if (publishId > 0) {
0796: rs = stmt
0797: .executeQuery("SELECT CHAN_NAME FROM UP_CHANNEL WHERE CHAN_ID="
0798: + publishId);
0799: try {
0800: if (rs.next()) {
0801: channelDesc.setName(rs.getString(1));
0802: fillChannelDescription(channelDesc);
0803: }
0804: } finally {
0805: rs.close();
0806: rs = null;
0807: }
0808: }
0809: }
0810:
0811: ALNode resultNode = addUserLayoutNode(userId, layoutId,
0812: node, psAddNode, psAddRestriction, null, null, stmt);
0813:
0814: stmt.close();
0815: stmt = null;
0816:
0817: return resultNode;
0818:
0819: } catch (Exception e) {
0820: e.printStackTrace();
0821: String errorMessage = e.getMessage();
0822: try {
0823: RDBMServices.rollback(con);
0824: } catch (SQLException sqle) {
0825: log.error(sqle.toString());
0826: errorMessage += ":" + sqle.getMessage();
0827: }
0828: throw new PortalException(errorMessage, e);
0829: } finally {
0830: try {
0831: // Ensure resouces are closed/cleaned-up
0832: if (rs != null)
0833: rs.close();
0834: if (stmt != null)
0835: stmt.close();
0836: if (psAddNode != null)
0837: psAddNode.close();
0838: if (psAddRestriction != null)
0839: psAddRestriction.close();
0840: } catch (Exception e) {
0841: log
0842: .error("AggregatedUserLayoutStore::addUserLayoutNode(): Failed to clean up resources.");
0843: }
0844: }
0845: }
0846:
0847: /**
0848: * Add the new user layout node.
0849: * @param userId the user
0850: * @param layoutId identities the layout
0851: * @param node a <code>ALNode</code> object specifying the node
0852: * @return a <code>ALNode</code> object specifying the node with the generated node ID
0853: * @exception PortalException if an error occurs
0854: */
0855: private ALNode addUserLayoutNode(int userId, int layoutId,
0856: ALNode node, PreparedStatement psAddNode,
0857: PreparedStatement psAddRestriction,
0858: PreparedStatement psAddChannel,
0859: PreparedStatement psAddChannelParam, Statement stmt)
0860: throws PortalException {
0861:
0862: IALNodeDescription nodeDesc = (IALNodeDescription) node
0863: .getNodeDescription();
0864:
0865: boolean isFolder = (node.getNodeType() == IUserLayoutNodeDescription.FOLDER);
0866: int fragmentId = CommonUtils.parseInt(nodeDesc.getFragmentId());
0867: int fragmentNodeId = CommonUtils.parseInt(nodeDesc
0868: .getFragmentNodeId());
0869: int nodeId = CommonUtils.parseInt(nodeDesc.getId());
0870: int tmpValue = -1;
0871:
0872: try {
0873:
0874: // if the node is in the fragment
0875: if (fragmentId > 0 && fragmentNodeId <= 0) {
0876:
0877: psAddNode.setInt(1, fragmentId);
0878: psAddNode.setInt(2, nodeId);
0879:
0880: tmpValue = CommonUtils.parseInt(node.getNextNodeId());
0881: if (tmpValue > 0)
0882: psAddNode.setInt(3, tmpValue);
0883: else
0884: psAddNode.setNull(3, Types.INTEGER);
0885:
0886: tmpValue = CommonUtils.parseInt(node
0887: .getPreviousNodeId());
0888: if (tmpValue > 0)
0889: psAddNode.setInt(4, tmpValue);
0890: else
0891: psAddNode.setNull(4, Types.INTEGER);
0892:
0893: tmpValue = (isFolder) ? CommonUtils
0894: .parseInt(((ALFolder) node)
0895: .getFirstChildNodeId()) : -1;
0896: if (tmpValue > 0)
0897: psAddNode.setInt(5, tmpValue);
0898: else
0899: psAddNode.setNull(5, Types.INTEGER);
0900:
0901: tmpValue = CommonUtils.parseInt(node.getParentNodeId());
0902: if (tmpValue > 0)
0903: psAddNode.setInt(6, tmpValue);
0904: else
0905: psAddNode.setNull(6, Types.INTEGER);
0906:
0907: psAddNode.setNull(7, Types.VARCHAR);
0908:
0909: tmpValue = (!isFolder) ? CommonUtils
0910: .parseInt(((IALChannelDescription) nodeDesc)
0911: .getChannelPublishId()) : -1;
0912: if (tmpValue > 0)
0913: psAddNode.setInt(8, tmpValue);
0914: else
0915: psAddNode.setNull(8, Types.INTEGER);
0916:
0917: psAddNode.setString(9, nodeDesc.getName());
0918: if (isFolder) {
0919: IALFolderDescription folderDesc = (IALFolderDescription) nodeDesc;
0920: int type = folderDesc.getFolderType();
0921: switch (type) {
0922: case UserLayoutFolderDescription.HEADER_TYPE:
0923: psAddNode.setString(10, "header");
0924: break;
0925: case UserLayoutFolderDescription.FOOTER_TYPE:
0926: psAddNode.setString(10, "footer");
0927: break;
0928: default:
0929: psAddNode.setString(10, "regular");
0930: }
0931: } else
0932: psAddNode.setNull(10, Types.VARCHAR);
0933:
0934: psAddNode.setString(11, (nodeDesc.isHidden()) ? "Y"
0935: : "N");
0936: psAddNode.setString(12, (nodeDesc.isImmutable()) ? "Y"
0937: : "N");
0938: psAddNode.setString(13,
0939: (nodeDesc.isUnremovable()) ? "Y" : "N");
0940: psAddNode.setString(14, nodeDesc.getGroup());
0941: psAddNode.setInt(15, node.getPriority());
0942:
0943: //execute update layout
0944: psAddNode.executeUpdate();
0945:
0946: // if fragment ID < 0
0947: } else {
0948:
0949: psAddNode.setInt(1, layoutId);
0950: psAddNode.setInt(2, userId);
0951: psAddNode.setInt(3, nodeId);
0952:
0953: tmpValue = CommonUtils.parseInt(node.getNextNodeId());
0954: if (tmpValue > 0)
0955: psAddNode.setInt(4, tmpValue);
0956: else
0957: psAddNode.setNull(4, Types.INTEGER);
0958:
0959: tmpValue = CommonUtils.parseInt(node
0960: .getPreviousNodeId());
0961: if (tmpValue > 0)
0962: psAddNode.setInt(5, tmpValue);
0963: else
0964: psAddNode.setNull(5, Types.INTEGER);
0965:
0966: tmpValue = (isFolder) ? CommonUtils
0967: .parseInt(((ALFolder) node)
0968: .getFirstChildNodeId()) : -1;
0969: if (tmpValue > 0)
0970: psAddNode.setInt(6, tmpValue);
0971: else
0972: psAddNode.setNull(6, Types.INTEGER);
0973:
0974: String parentId = node.getParentNodeId();
0975: if (!IALFolderDescription.ROOT_FOLDER_ID
0976: .equals(parentId))
0977: psAddNode.setInt(7, CommonUtils.parseInt(parentId,
0978: LOST_FOLDER_ID));
0979: else
0980: psAddNode.setNull(7, Types.INTEGER);
0981:
0982: psAddNode.setNull(8, Types.VARCHAR);
0983:
0984: tmpValue = (!isFolder) ? CommonUtils
0985: .parseInt(((IALChannelDescription) nodeDesc)
0986: .getChannelPublishId()) : -1;
0987: if (tmpValue > 0)
0988: psAddNode.setInt(9, tmpValue);
0989: else
0990: psAddNode.setNull(9, Types.INTEGER);
0991:
0992: psAddNode.setString(10, nodeDesc.getName());
0993:
0994: if (isFolder) {
0995: IALFolderDescription folderDesc = (IALFolderDescription) nodeDesc;
0996: int type = folderDesc.getFolderType();
0997: switch (type) {
0998: case UserLayoutFolderDescription.HEADER_TYPE:
0999: psAddNode.setString(11, "header");
1000: break;
1001: case UserLayoutFolderDescription.FOOTER_TYPE:
1002: psAddNode.setString(11, "footer");
1003: break;
1004: default:
1005: psAddNode.setString(11, "regular");
1006: }
1007: } else
1008: psAddNode.setNull(11, Types.VARCHAR);
1009:
1010: psAddNode.setString(12, (nodeDesc.isHidden()) ? "Y"
1011: : "N");
1012: psAddNode.setString(13, (nodeDesc.isImmutable()) ? "Y"
1013: : "N");
1014: psAddNode.setString(14,
1015: (nodeDesc.isUnremovable()) ? "Y" : "N");
1016: psAddNode.setString(15, nodeDesc.getGroup());
1017: psAddNode.setInt(16, node.getPriority());
1018: if (fragmentId > 0)
1019: psAddNode.setInt(17, fragmentId);
1020: else
1021: psAddNode.setNull(17, Types.INTEGER);
1022:
1023: if (fragmentNodeId > 0)
1024: psAddNode.setInt(18, fragmentNodeId);
1025: else
1026: psAddNode.setNull(18, Types.INTEGER);
1027:
1028: //execute update layout
1029: psAddNode.executeUpdate();
1030: }
1031:
1032: // Insert node restrictions
1033: Hashtable restrHash = nodeDesc.getRestrictions();
1034: if (restrHash != null) {
1035:
1036: if (fragmentId > 0 && layoutId < 0) {
1037:
1038: Enumeration restrictions = restrHash.elements();
1039:
1040: for (; restrictions.hasMoreElements();) {
1041: IUserLayoutRestriction restriction = (IUserLayoutRestriction) restrictions
1042: .nextElement();
1043:
1044: psAddRestriction.setString(1, restriction
1045: .getName());
1046: psAddRestriction.setInt(2, nodeId);
1047: psAddRestriction.setInt(3, fragmentId);
1048: psAddRestriction.setString(4, restriction
1049: .getRestrictionExpression());
1050:
1051: String path = restriction.getRestrictionPath();
1052: psAddRestriction.setString(5, path);
1053:
1054: //execute update restrictions
1055: psAddRestriction.executeUpdate();
1056:
1057: }
1058:
1059: } else if (fragmentId <= 0) {
1060:
1061: Enumeration restrictions = restrHash.elements();
1062:
1063: for (; restrictions.hasMoreElements();) {
1064: IUserLayoutRestriction restriction = (IUserLayoutRestriction) restrictions
1065: .nextElement();
1066:
1067: psAddRestriction.setString(1, restriction
1068: .getName());
1069: psAddRestriction.setInt(2, layoutId);
1070: psAddRestriction.setInt(3, userId);
1071: psAddRestriction.setInt(4, nodeId);
1072: psAddRestriction.setString(5, restriction
1073: .getRestrictionExpression());
1074:
1075: String path = restriction.getRestrictionPath();
1076: psAddRestriction.setString(6, path);
1077:
1078: //execute update restrictions
1079: psAddRestriction.executeUpdate();
1080:
1081: } // end for
1082:
1083: } // end else
1084:
1085: } // end if
1086:
1087: // if we have channel parameters
1088: if (!isFolder && psAddChannel != null
1089: && psAddChannelParam != null) {
1090:
1091: IALChannelDescription channelDesc = (IALChannelDescription) nodeDesc;
1092:
1093: int publishId = CommonUtils.parseInt(channelDesc
1094: .getChannelPublishId());
1095: if (publishId > 0) {
1096:
1097: for (Enumeration paramNames = channelDesc
1098: .getParameterNames(); paramNames
1099: .hasMoreElements();) {
1100: String paramName = (String) paramNames
1101: .nextElement();
1102: String paramValue = channelDesc
1103: .getParameterValue(paramName);
1104:
1105: psAddChannelParam.setInt(1, publishId);
1106:
1107: psAddChannelParam.setString(2, paramName);
1108: if (channelDesc.getDescription() != null)
1109: psAddChannelParam.setString(3, channelDesc
1110: .getDescription());
1111: else
1112: psAddChannelParam.setNull(3, Types.VARCHAR);
1113: psAddChannelParam.setString(4, paramValue);
1114: psAddChannelParam.setString(5, (channelDesc
1115: .canOverrideParameter(paramName)) ? "Y"
1116: : "N");
1117:
1118: //execute update parameters
1119: psAddChannelParam.executeUpdate();
1120: }
1121:
1122: // Inserting channel attributes
1123: psAddChannel.setInt(1, publishId);
1124:
1125: psAddChannel.setString(2, channelDesc.getTitle());
1126: psAddChannel.setString(3, channelDesc.getName());
1127: if (channelDesc.getDescription() != null)
1128: psAddChannel.setString(4, channelDesc
1129: .getDescription());
1130: else
1131: psAddChannel.setNull(4, Types.VARCHAR);
1132: psAddChannel.setString(5, channelDesc
1133: .getClassName());
1134: tmpValue = CommonUtils.parseInt(channelDesc
1135: .getChannelTypeId());
1136: if (tmpValue > 0)
1137: psAddChannel.setInt(6, tmpValue);
1138: else
1139: psAddChannel.setNull(6, Types.INTEGER);
1140:
1141: tmpValue = CommonUtils.parseInt(channelDesc
1142: .getChannelPublishId());
1143: if (tmpValue > 0)
1144: psAddChannel.setInt(7, tmpValue);
1145: else
1146: psAddChannel.setNull(7, Types.INTEGER);
1147:
1148: Timestamp timestamp = new java.sql.Timestamp(
1149: new Date().getTime());
1150: psAddChannel.setTimestamp(8, timestamp);
1151: psAddChannel.setInt(9, 0);
1152: psAddChannel.setTimestamp(10, timestamp);
1153: psAddChannel.setInt(11, (int) channelDesc
1154: .getTimeout());
1155: psAddChannel.setString(12, (channelDesc
1156: .isEditable()) ? "Y" : "N");
1157: psAddChannel.setString(13,
1158: (channelDesc.hasHelp()) ? "Y" : "N");
1159: psAddChannel.setString(14,
1160: (channelDesc.hasAbout()) ? "Y" : "N");
1161: psAddChannel.setString(15, channelDesc
1162: .getFunctionalName());
1163:
1164: //execute update parameters
1165: psAddChannel.executeUpdate();
1166: }
1167: }
1168:
1169: return node;
1170:
1171: } catch (Exception e) {
1172: log.error(e, e);
1173: throw new PortalException(e);
1174: }
1175:
1176: }
1177:
1178: /**
1179: * Update the new user layout node.
1180: * @param person an <code>IPerson</code> object specifying the user
1181: * @param profile a user profile for which the layout is being stored
1182: * @param node a <code>ALNode</code> object specifying the node
1183: * @param con The connection to be used to perform all database operations.
1184: * @return a boolean result of this operation
1185: * @exception PortalException if an error occurs
1186: */
1187: private boolean updateUserLayoutNode(IPerson person,
1188: UserProfile profile, ALNode node, Connection con)
1189: throws PortalException {
1190:
1191: Statement stmt = null;
1192: ResultSet rs = null;
1193: PreparedStatement psUpdateNode = null;
1194: PreparedStatement psUpdateRestriction = null;
1195:
1196: try {
1197:
1198: int userId = person.getID();
1199: int nodeId = CommonUtils.parseInt(node.getId());
1200: IALNodeDescription nodeDesc = (IALNodeDescription) node
1201: .getNodeDescription();
1202:
1203: stmt = con.createStatement();
1204:
1205: // eventually, we need to fix template layout implementations so you can just do this:
1206: // int layoutId=profile.getLayoutId();
1207: // but for now:
1208: String subSelectString = "SELECT LAYOUT_ID FROM UP_USER_PROFILE WHERE USER_ID="
1209: + userId
1210: + " AND PROFILE_ID="
1211: + profile.getProfileId();
1212: //log.debug( "RDBMUserLayoutStore::getUserLayout(): " + subSelectString);
1213: int layoutId = -1;
1214: rs = stmt.executeQuery(subSelectString);
1215: try {
1216: if (rs.next())
1217: layoutId = rs.getInt(1);
1218: } finally {
1219: rs.close();
1220: rs = null;
1221: }
1222:
1223: int fragmentId = CommonUtils.parseInt(nodeDesc
1224: .getFragmentId());
1225: int fragmentNodeId = CommonUtils.parseInt(nodeDesc
1226: .getFragmentNodeId());
1227:
1228: if (fragmentId > 0 && fragmentNodeId <= 0)
1229: psUpdateNode = con
1230: .prepareStatement(FRAGMENT_UPDATE_SQL);
1231: else
1232: psUpdateNode = con.prepareStatement(LAYOUT_UPDATE_SQL);
1233:
1234: if (fragmentId > 0) {
1235: psUpdateRestriction = con
1236: .prepareStatement(FRAGMENT_RESTRICTION_UPDATE_SQL);
1237: } else {
1238: psUpdateRestriction = con
1239: .prepareStatement(LAYOUT_RESTRICTION_UPDATE_SQL);
1240: }
1241:
1242: boolean result = updateUserLayoutNode(userId, layoutId,
1243: node, psUpdateNode, psUpdateRestriction, null, null);
1244:
1245: RDBMServices.commit(con);
1246:
1247: // Closing
1248: stmt.close();
1249: stmt = null;
1250:
1251: return result;
1252:
1253: } catch (Exception e) {
1254: e.printStackTrace();
1255: String errorMessage = e.getMessage();
1256: try {
1257: RDBMServices.rollback(con);
1258: } catch (SQLException sqle) {
1259: log.error(sqle.toString());
1260: errorMessage += ":" + sqle.getMessage();
1261: }
1262: throw new PortalException(errorMessage, e);
1263: } finally {
1264: try {
1265: // Ensure resouces are closed/cleaned-up
1266: if (rs != null)
1267: rs.close();
1268: if (stmt != null)
1269: stmt.close();
1270: if (psUpdateNode != null)
1271: psUpdateNode.close();
1272: if (psUpdateRestriction != null)
1273: psUpdateRestriction.close();
1274: } catch (Exception e) {
1275: log
1276: .error("AggregatedUserLayoutStore::updateUserLayoutNode(): Failed to clean up resources.");
1277: }
1278: }
1279: }
1280:
1281: /**
1282: * Update the new user layout node.
1283: * @param userId the user
1284: * @param layoutId identities the layout is being stored
1285: * @param node a <code>ALNode</code> object specifying the node
1286: * @return a boolean result of this operation
1287: * @exception PortalException if an error occurs
1288: */
1289: private boolean updateUserLayoutNode(int userId, int layoutId,
1290: ALNode node, PreparedStatement psUpdateNode,
1291: PreparedStatement psUpdateRestriction,
1292: PreparedStatement psUpdateChannel,
1293: PreparedStatement psUpdateChannelParam)
1294: throws PortalException {
1295:
1296: int count = 0;
1297:
1298: boolean isFolder = (node.getNodeType() == IUserLayoutNodeDescription.FOLDER);
1299: IALNodeDescription nodeDesc = (IALNodeDescription) node
1300: .getNodeDescription();
1301: int nodeId = CommonUtils.parseInt(nodeDesc.getId());
1302: int fragmentId = CommonUtils.parseInt(nodeDesc.getFragmentId());
1303: int fragmentNodeId = CommonUtils.parseInt(nodeDesc
1304: .getFragmentNodeId());
1305: int tmpValue = -1;
1306:
1307: try {
1308:
1309: if (fragmentId > 0 && fragmentNodeId <= 0) {
1310:
1311: tmpValue = CommonUtils.parseInt(node.getNextNodeId());
1312: if (tmpValue > 0)
1313: psUpdateNode.setInt(1, tmpValue);
1314: else
1315: psUpdateNode.setNull(1, Types.INTEGER);
1316:
1317: tmpValue = CommonUtils.parseInt(node
1318: .getPreviousNodeId());
1319: if (tmpValue > 0)
1320: psUpdateNode.setInt(2, tmpValue);
1321: else
1322: psUpdateNode.setNull(2, Types.INTEGER);
1323:
1324: tmpValue = (isFolder) ? CommonUtils
1325: .parseInt(((ALFolder) node)
1326: .getFirstChildNodeId()) : -1;
1327: if (tmpValue > 0)
1328: psUpdateNode.setInt(3, tmpValue);
1329: else
1330: psUpdateNode.setNull(3, Types.INTEGER);
1331:
1332: tmpValue = CommonUtils.parseInt(node.getParentNodeId());
1333: if (tmpValue > 0)
1334: psUpdateNode.setInt(4, tmpValue);
1335: else
1336: psUpdateNode.setNull(4, Types.INTEGER);
1337:
1338: psUpdateNode.setNull(5, Types.VARCHAR);
1339:
1340: tmpValue = (!isFolder) ? CommonUtils
1341: .parseInt(((IALChannelDescription) nodeDesc)
1342: .getChannelPublishId()) : -1;
1343: if (tmpValue > 0)
1344: psUpdateNode.setInt(6, tmpValue);
1345: else
1346: psUpdateNode.setNull(6, Types.INTEGER);
1347:
1348: psUpdateNode.setString(7, nodeDesc.getName());
1349: if (isFolder) {
1350: IALFolderDescription folderDesc = (IALFolderDescription) nodeDesc;
1351: int type = folderDesc.getFolderType();
1352: switch (type) {
1353: case UserLayoutFolderDescription.HEADER_TYPE:
1354: psUpdateNode.setString(8, "header");
1355: break;
1356: case UserLayoutFolderDescription.FOOTER_TYPE:
1357: psUpdateNode.setString(8, "footer");
1358: break;
1359: default:
1360: psUpdateNode.setString(8, "regular");
1361: }
1362: } else
1363: psUpdateNode.setNull(8, Types.VARCHAR);
1364:
1365: psUpdateNode.setString(9, (nodeDesc.isHidden()) ? "Y"
1366: : "N");
1367: psUpdateNode.setString(10,
1368: (nodeDesc.isImmutable()) ? "Y" : "N");
1369: psUpdateNode.setString(11,
1370: (nodeDesc.isUnremovable()) ? "Y" : "N");
1371: psUpdateNode.setString(12, nodeDesc.getGroup());
1372:
1373: psUpdateNode.setInt(13, node.getPriority());
1374:
1375: psUpdateNode.setInt(14, fragmentId);
1376: psUpdateNode.setInt(15, nodeId);
1377:
1378: //execute update layout
1379: count += psUpdateNode.executeUpdate();
1380:
1381: // if fragment id <= 0
1382: } else {
1383:
1384: tmpValue = CommonUtils.parseInt(node.getNextNodeId());
1385: if (tmpValue > 0)
1386: psUpdateNode.setInt(1, tmpValue);
1387: else
1388: psUpdateNode.setNull(1, Types.INTEGER);
1389:
1390: tmpValue = CommonUtils.parseInt(node
1391: .getPreviousNodeId());
1392: if (tmpValue > 0)
1393: psUpdateNode.setInt(2, tmpValue);
1394: else
1395: psUpdateNode.setNull(2, Types.INTEGER);
1396:
1397: tmpValue = (isFolder) ? CommonUtils
1398: .parseInt(((ALFolder) node)
1399: .getFirstChildNodeId()) : -1;
1400: if (tmpValue > 0)
1401: psUpdateNode.setInt(3, tmpValue);
1402: else
1403: psUpdateNode.setNull(3, Types.INTEGER);
1404:
1405: String parentId = node.getParentNodeId();
1406: if (!IALFolderDescription.ROOT_FOLDER_ID
1407: .equals(parentId))
1408: psUpdateNode.setInt(4, CommonUtils.parseInt(
1409: parentId, LOST_FOLDER_ID));
1410: else
1411: psUpdateNode.setNull(4, Types.INTEGER);
1412:
1413: psUpdateNode.setNull(5, Types.VARCHAR);
1414:
1415: tmpValue = (!isFolder) ? CommonUtils
1416: .parseInt(((IALChannelDescription) nodeDesc)
1417: .getChannelPublishId()) : -1;
1418: if (tmpValue > 0)
1419: psUpdateNode.setInt(6, tmpValue);
1420: else
1421: psUpdateNode.setNull(6, Types.INTEGER);
1422:
1423: psUpdateNode.setString(7, nodeDesc.getName());
1424:
1425: if (isFolder) {
1426: IALFolderDescription folderDesc = (IALFolderDescription) nodeDesc;
1427: int type = folderDesc.getFolderType();
1428: switch (type) {
1429: case UserLayoutFolderDescription.HEADER_TYPE:
1430: psUpdateNode.setString(8, "header");
1431: break;
1432: case UserLayoutFolderDescription.FOOTER_TYPE:
1433: psUpdateNode.setString(8, "footer");
1434: break;
1435: default:
1436: psUpdateNode.setString(8, "regular");
1437: }
1438: } else
1439: psUpdateNode.setNull(8, Types.VARCHAR);
1440:
1441: psUpdateNode.setString(9, (nodeDesc.isHidden()) ? "Y"
1442: : "N");
1443: psUpdateNode.setString(10,
1444: (nodeDesc.isImmutable()) ? "Y" : "N");
1445: psUpdateNode.setString(11,
1446: (nodeDesc.isUnremovable()) ? "Y" : "N");
1447: psUpdateNode.setString(12, nodeDesc.getGroup());
1448: psUpdateNode.setInt(13, node.getPriority());
1449:
1450: if (fragmentId > 0)
1451: psUpdateNode.setInt(14, fragmentId);
1452: else
1453: psUpdateNode.setNull(14, Types.INTEGER);
1454:
1455: if (fragmentNodeId > 0)
1456: psUpdateNode.setInt(15, fragmentNodeId);
1457: else
1458: psUpdateNode.setNull(15, Types.INTEGER);
1459:
1460: psUpdateNode.setInt(16, layoutId);
1461: psUpdateNode.setInt(17, userId);
1462: psUpdateNode.setInt(18, nodeId);
1463:
1464: //execute update layout
1465: count += psUpdateNode.executeUpdate();
1466:
1467: }
1468:
1469: // Insert node restrictions
1470: Hashtable restrHash = nodeDesc.getRestrictions();
1471: if (restrHash != null) {
1472:
1473: if (fragmentId > 0 && layoutId < 0) {
1474:
1475: Enumeration restrictions = restrHash.elements();
1476: for (; restrictions.hasMoreElements();) {
1477: IUserLayoutRestriction restriction = (IUserLayoutRestriction) restrictions
1478: .nextElement();
1479:
1480: psUpdateRestriction.setString(1, restriction
1481: .getRestrictionExpression());
1482: psUpdateRestriction.setInt(2, fragmentId);
1483: psUpdateRestriction.setInt(3, nodeId);
1484: psUpdateRestriction.setString(4, restriction
1485: .getName());
1486:
1487: String path = restriction.getRestrictionPath();
1488: psUpdateRestriction.setString(5, path);
1489:
1490: //execute update restrictions
1491: count += psUpdateRestriction.executeUpdate();
1492: } // end for */
1493:
1494: } else if (fragmentId <= 0) {
1495:
1496: Enumeration restrictions = restrHash.elements();
1497: for (; restrictions.hasMoreElements();) {
1498: IUserLayoutRestriction restriction = (IUserLayoutRestriction) restrictions
1499: .nextElement();
1500:
1501: psUpdateRestriction.setString(1, restriction
1502: .getRestrictionExpression());
1503: psUpdateRestriction.setInt(2, layoutId);
1504: psUpdateRestriction.setInt(3, userId);
1505: psUpdateRestriction.setInt(4, nodeId);
1506: psUpdateRestriction.setString(5, restriction
1507: .getName());
1508:
1509: String path = restriction.getRestrictionPath();
1510: psUpdateRestriction.setString(6, path);
1511:
1512: //execute update restrictions
1513: count += psUpdateRestriction.executeUpdate();
1514:
1515: } // end for
1516: } // end else
1517: } // end if
1518: return count > 0;
1519:
1520: } catch (Exception e) {
1521: log.error(e, e);
1522: throw new PortalException(e);
1523: }
1524: }
1525:
1526: /**
1527: * Delete the new user layout node.
1528: * @param person an <code>IPerson</code> object specifying the user
1529: * @param profile a user profile for which the layout is being stored
1530: * @param node a <code>ALNode</code> node ID specifying the node
1531: * @param con The connection to be used to perform all database operations.
1532: * @return a boolean result of this operation
1533: * @exception PortalException if an error occurs
1534: */
1535: private boolean deleteUserLayoutNode(IPerson person,
1536: UserProfile profile, ALNode node, Connection con)
1537: throws PortalException {
1538:
1539: Statement stmt = null;
1540: ResultSet rs = null;
1541: PreparedStatement psFragmentRestr = null;
1542: PreparedStatement psRestr = null;
1543: PreparedStatement psFragment = null;
1544: PreparedStatement psLayout = null;
1545:
1546: try {
1547:
1548: int count = 0;
1549: int userId = person.getID();
1550: int nodeId = CommonUtils.parseInt(node.getId());
1551: IALNodeDescription nodeDesc = (IALNodeDescription) node
1552: .getNodeDescription();
1553:
1554: stmt = con.createStatement();
1555:
1556: // eventually, we need to fix template layout implementations so you can just do this:
1557: // int layoutId=profile.getLayoutId();
1558: // but for now:
1559: String subSelectString = "SELECT LAYOUT_ID FROM UP_USER_PROFILE WHERE USER_ID="
1560: + userId
1561: + " AND PROFILE_ID="
1562: + profile.getProfileId();
1563: log
1564: .debug("AggregatedUserLayoutStore::deleteUserLayoutNode(): "
1565: + subSelectString);
1566: int layoutId = -1;
1567: rs = stmt.executeQuery(subSelectString);
1568: try {
1569: if (rs.next())
1570: layoutId = rs.getInt(1);
1571: } finally {
1572: rs.close();
1573: rs = null;
1574: }
1575:
1576: stmt.close();
1577: stmt = null;
1578:
1579: boolean isFolder = (node.getNodeType() == IUserLayoutNodeDescription.FOLDER);
1580: int fragmentId = CommonUtils.parseInt(node.getFragmentId());
1581: int fragmentNodeId = CommonUtils.parseInt(node
1582: .getFragmentNodeId());
1583: int tmpValue = -1;
1584:
1585: // Delete node restrictions
1586: Hashtable restrHash = nodeDesc.getRestrictions();
1587: if (restrHash != null) {
1588:
1589: if (fragmentId > 0 && layoutId < 0) {
1590:
1591: psFragmentRestr = con
1592: .prepareStatement("DELETE FROM UP_FRAGMENT_RESTRICTIONS"
1593: + " WHERE FRAGMENT_ID=? AND NODE_ID=? AND RESTRICTION_NAME=? AND RESTRICTION_TREE_PATH=?");
1594: Enumeration restrictions = restrHash.elements();
1595: for (; restrictions.hasMoreElements();) {
1596: IUserLayoutRestriction restriction = (IUserLayoutRestriction) restrictions
1597: .nextElement();
1598:
1599: psFragmentRestr.setInt(1, fragmentId);
1600: psFragmentRestr.setInt(2, nodeId);
1601: psFragmentRestr.setString(3, restriction
1602: .getName());
1603:
1604: String path = restriction.getRestrictionPath();
1605: psFragmentRestr.setString(4, path);
1606:
1607: //execute update restrictions
1608: count += psFragmentRestr.executeUpdate();
1609: } // end for
1610:
1611: // Clean up
1612: psFragmentRestr.close();
1613: psFragmentRestr = null;
1614:
1615: // fragment ID is null
1616: } else if (fragmentId <= 0) {
1617:
1618: psRestr = con
1619: .prepareStatement("DELETE FROM UP_LAYOUT_RESTRICTIONS"
1620: + " WHERE LAYOUT_ID=? AND USER_ID=? AND NODE_ID=? AND RESTRICTION_NAME=? AND RESTRICTION_TREE_PATH=?");
1621:
1622: Enumeration restrictions = restrHash.elements();
1623: for (; restrictions.hasMoreElements();) {
1624: IUserLayoutRestriction restriction = (IUserLayoutRestriction) restrictions
1625: .nextElement();
1626:
1627: psRestr.setInt(1, layoutId);
1628: psRestr.setInt(2, userId);
1629: psRestr.setInt(3, nodeId);
1630: psRestr.setString(4, restriction.getName());
1631:
1632: String path = restriction.getRestrictionPath();
1633: psRestr.setString(5, path);
1634:
1635: //execute update restrictions
1636: count += psRestr.executeUpdate();
1637: } // end for
1638:
1639: // Clean-up
1640: psRestr.close();
1641: psRestr = null;
1642:
1643: } // end if for fragment ID
1644: } // end if
1645:
1646: if (fragmentId > 0 && fragmentNodeId <= 0) {
1647: psFragment = con
1648: .prepareStatement("DELETE FROM UP_FRAGMENTS WHERE NODE_ID=? AND FRAGMENT_ID=?");
1649:
1650: psFragment.setInt(1, nodeId);
1651: psFragment.setInt(2, fragmentId);
1652:
1653: //execute update layout
1654: count += psFragment.executeUpdate();
1655: psFragment.close();
1656: psFragment = null;
1657:
1658: } else {
1659: psLayout = con
1660: .prepareStatement("DELETE FROM UP_LAYOUT_STRUCT_AGGR WHERE LAYOUT_ID=? AND USER_ID=? AND NODE_ID=?");
1661:
1662: psLayout.setInt(1, layoutId);
1663: psLayout.setInt(2, userId);
1664: psLayout.setInt(3, nodeId);
1665:
1666: //execute update layout
1667: count += psLayout.executeUpdate();
1668: psLayout.close();
1669: psLayout = null;
1670: }
1671:
1672: RDBMServices.commit(con);
1673:
1674: return count > 0;
1675:
1676: } catch (Exception e) {
1677: e.printStackTrace();
1678: String errorMessage = e.getMessage();
1679: try {
1680: RDBMServices.rollback(con);
1681: } catch (SQLException sqle) {
1682: log.error(sqle.toString());
1683: errorMessage += ":" + sqle.getMessage();
1684: }
1685: throw new PortalException(errorMessage, e);
1686: } finally {
1687: try {
1688: // Ensure resouces are closed/cleaned-up
1689: if (rs != null)
1690: rs.close();
1691: if (stmt != null)
1692: stmt.close();
1693: if (psFragmentRestr != null)
1694: psFragmentRestr.close();
1695: if (psRestr != null)
1696: psRestr.close();
1697: if (psFragment != null)
1698: psFragment.close();
1699: if (psLayout != null)
1700: psLayout.close();
1701: } catch (Exception e) {
1702: log
1703: .error("AggregatedUserLayoutStore::deleteUserLayoutNode(): Failed to clean up resources.");
1704: }
1705: }
1706: }
1707:
1708: /**
1709: * @param person an <code>IPerson</code> object specifying the user
1710: * @param profile a user profile for which the layout is being stored
1711: * @param layoutImpl a <code>IAggregatedLayout</code> containing an aggregated user layout
1712: * @exception PortalException if an error occurs
1713: */
1714: public synchronized void setAggregatedLayout(IPerson person,
1715: UserProfile profile, IAggregatedLayout layoutImpl)
1716: throws PortalException {
1717:
1718: if (!(layoutImpl instanceof AggregatedLayout))
1719: throw new PortalException(
1720: "The user layout object should have \"AggregatedLayout\" type");
1721:
1722: AggregatedLayout layout = (AggregatedLayout) layoutImpl;
1723: int userId = person.getID();
1724: int profileId = profile.getProfileId();
1725: int layoutId = Integer.parseInt(layoutImpl.getId());
1726:
1727: Connection con = null;
1728:
1729: try {
1730:
1731: con = RDBMServices.getConnection();
1732: RDBMServices.setAutoCommit(con, false);
1733:
1734: PreparedStatement psSelect = null;
1735: final String sQuery = "SELECT LAYOUT_ID FROM UP_USER_PROFILE WHERE USER_ID=? AND PROFILE_ID=?";
1736: try {
1737: psSelect = con.prepareStatement(sQuery);
1738: psSelect.setInt(1, userId);
1739: psSelect.setInt(2, profileId);
1740: ResultSet rs = null;
1741: try {
1742: rs = psSelect.executeQuery();
1743: if (rs.next()) {
1744: rs.getInt(1);
1745: if (rs.wasNull()) {
1746: final String sUpdateProfileQuery = "UPDATE UP_USER_PROFILE SET LAYOUT_ID=? WHERE USER_ID=? AND PROFILE_ID=?";
1747: PreparedStatement psUpdateUserProfile = null;
1748: try {
1749: psUpdateUserProfile = con
1750: .prepareStatement(sUpdateProfileQuery);
1751: psUpdateUserProfile.setInt(1, layoutId);
1752: psUpdateUserProfile.setInt(2, userId);
1753: psUpdateUserProfile
1754: .setInt(3, profileId);
1755: if (log.isDebugEnabled())
1756: log
1757: .debug("AggregatedUserLayoutStore::setAggregatedLayout(): "
1758: + sUpdateProfileQuery);
1759: psUpdateUserProfile.executeUpdate();
1760: } finally {
1761: if (psUpdateUserProfile != null) {
1762: try {
1763: psUpdateUserProfile.close();
1764: } catch (Exception e) {
1765: }
1766: }
1767: }
1768: }
1769: }
1770: } finally {
1771: if (rs != null) {
1772: try {
1773: rs.close();
1774: } catch (Exception e) {
1775: }
1776: }
1777: }
1778: } finally {
1779: if (psSelect != null) {
1780: try {
1781: psSelect.close();
1782: } catch (Exception e) {
1783: }
1784: }
1785: }
1786:
1787: // Update the user's layout node set and write new node restrictions
1788: updateUserLayoutNodes(person, profile, layout, con);
1789:
1790: final String sSelectInitQuery = "SELECT INIT_NODE_ID FROM UP_USER_LAYOUT_AGGR WHERE USER_ID=? AND LAYOUT_ID=?";
1791: if (log.isDebugEnabled())
1792: log
1793: .debug("AggregatedUserLayoutStore::setAggregatedLayout(): "
1794: + sSelectInitQuery);
1795: String firstNodeId = layout.getLayoutFolder(
1796: layout.getRootId()).getFirstChildNodeId();
1797: PreparedStatement psSelectInit = null;
1798: try {
1799: psSelectInit = con.prepareStatement(sSelectInitQuery);
1800: psSelectInit.setInt(1, userId);
1801: psSelectInit.setInt(2, layoutId);
1802: ResultSet rsInit = null;
1803: try {
1804: rsInit = psSelectInit.executeQuery();
1805: if (!rsInit.next()) {
1806: final String insertLayoutQuery = "INSERT INTO UP_USER_LAYOUT_AGGR (LAYOUT_ID,USER_ID,LAYOUT_TITLE,INIT_NODE_ID) VALUES (?,?,?,?)";
1807: PreparedStatement psInsertLayout = null;
1808: try {
1809: psInsertLayout = con
1810: .prepareStatement(insertLayoutQuery);
1811: psInsertLayout.setInt(1, layoutId);
1812: psInsertLayout.setInt(2, userId);
1813: psInsertLayout.setString(3, new String(
1814: person.getFullName() + " layout"));
1815: psInsertLayout.setInt(4, Integer
1816: .parseInt(firstNodeId));
1817: if (log.isDebugEnabled())
1818: log
1819: .debug("AggregatedUserLayoutStore::setAggregatedLayout(): "
1820: + insertLayoutQuery
1821: + " with values ("
1822: + layoutId
1823: + ", "
1824: + userId
1825: + ", "
1826: + new String(person
1827: .getFullName()
1828: + " layout")
1829: + ", "
1830: + firstNodeId
1831: + ")");
1832: psInsertLayout.executeUpdate();
1833: } finally {
1834: if (psInsertLayout != null) {
1835: try {
1836: psInsertLayout.close();
1837: } catch (Exception e) {
1838: }
1839: }
1840: }
1841: } else {
1842: final String sUpdateQuery = "UPDATE UP_USER_LAYOUT_AGGR SET INIT_NODE_ID=? WHERE LAYOUT_ID=? AND USER_ID=?";
1843: PreparedStatement psUpdateLayout = null;
1844: try {
1845: psUpdateLayout = con
1846: .prepareStatement(sUpdateQuery);
1847: psUpdateLayout.setInt(1, Integer
1848: .parseInt(firstNodeId));
1849: psUpdateLayout.setInt(2, layoutId);
1850: psUpdateLayout.setInt(3, userId);
1851: if (log.isDebugEnabled())
1852: log
1853: .debug("AggregatedUserLayoutStore::setAggregatedLayout(): "
1854: + sUpdateQuery);
1855: psUpdateLayout.executeUpdate();
1856: } finally {
1857: if (psUpdateLayout != null) {
1858: try {
1859: psUpdateLayout.close();
1860: } catch (Exception e) {
1861: }
1862: }
1863: }
1864: }
1865: } finally {
1866: if (rsInit != null) {
1867: try {
1868: rsInit.close();
1869: } catch (Exception e) {
1870: }
1871: }
1872: }
1873: } finally {
1874: if (psSelectInit != null) {
1875: try {
1876: psSelectInit.close();
1877: } catch (Exception e) {
1878: }
1879: }
1880: }
1881:
1882: // Commit all the changes
1883: RDBMServices.commit(con);
1884:
1885: } catch (Exception e) {
1886: log.error(e, e);
1887: try {
1888: RDBMServices.rollback(con);
1889: } catch (Exception ee) {
1890: /*ignore*/
1891: }
1892: throw new PortalException(e);
1893: } finally {
1894: RDBMServices.releaseConnection(con);
1895: }
1896: }
1897:
1898: /** Gets the fragment IDs/fragment descriptions for a given user
1899: * @param person an <code>IPerson</code> object specifying the user
1900: * @return a <code>Map</code> object containing the IDs of the fragments the user owns
1901: * @exception PortalException if an error occurs
1902: */
1903: public Map getFragments(IPerson person) throws PortalException {
1904: try {
1905: Connection con = RDBMServices.getConnection();
1906:
1907: Map fragments = new Hashtable();
1908: Statement stmt = con.createStatement();
1909: ResultSet rs = stmt
1910: .executeQuery("SELECT FRAGMENT_ID, FRAGMENT_DESCRIPTION FROM UP_OWNER_FRAGMENT WHERE OWNER_ID="
1911: + person.getID());
1912: while (rs.next()) {
1913: // Oracle will return nulls instead of the empty string.
1914: // Hashtable doesn't allow null values so we convert them
1915: // to "" before storing in the Hashtable.
1916: String col2 = rs.getString(2);
1917: if (col2 == null) {
1918: col2 = "";
1919: }
1920: fragments.put(rs.getInt(1) + "", col2);
1921: }
1922:
1923: if (rs != null)
1924: rs.close();
1925: if (stmt != null)
1926: stmt.close();
1927: if (con != null)
1928: con.close();
1929:
1930: return fragments;
1931: } catch (Exception e) {
1932: throw new PortalException(e);
1933: }
1934: }
1935:
1936: /** Sets the fragment
1937: * @param person an <code>IPerson</code> object specifying the user
1938: * @param fragment a <code>ILayoutFragment</code> containing a fragment
1939: * @exception PortalException if an error occurs
1940: */
1941: public void setFragment(IPerson person, ILayoutFragment fragment,
1942: UserPreferences userPrefs) throws PortalException {
1943:
1944: synchronized (fragmentLock) {
1945:
1946: int userId = person.getID();
1947: String fragmentId = fragment.getId();
1948: Connection con = null;
1949:
1950: if (!(fragment instanceof ALFragment))
1951: throw new PortalException(
1952: "The user layout fragment must have "
1953: + ALFragment.class.getName() + " type!");
1954:
1955: ALFragment layout = (ALFragment) fragment;
1956:
1957: Set currentNodeIds = new HashSet();
1958: Set newNodeIds = new HashSet();
1959:
1960: try {
1961: con = RDBMServices.getConnection();
1962:
1963: Statement stmt = con.createStatement();
1964:
1965: boolean isOwner = false;
1966: boolean isNewFragment = false;
1967: // Check if the user was an owner
1968: ResultSet rs = stmt
1969: .executeQuery("SELECT OWNER_ID FROM UP_OWNER_FRAGMENT WHERE FRAGMENT_ID="
1970: + fragmentId);
1971: if (rs.next()) {
1972: if (rs.getInt(1) == userId)
1973: isOwner = true;
1974: } else
1975: isNewFragment = true;
1976: if (rs != null)
1977: rs.close();
1978:
1979: if (!isOwner && !isNewFragment)
1980: throw new PortalException(
1981: "The user "
1982: + userId
1983: + " is not an owner of the fragment with ID="
1984: + fragmentId);
1985:
1986: // Add, update and delete prepared statements
1987: PreparedStatement psAddFragmentNode = con
1988: .prepareStatement(FRAGMENT_ADD_SQL);
1989: PreparedStatement psAddFragmentRestriction = con
1990: .prepareStatement(FRAGMENT_RESTRICTION_ADD_SQL);
1991: PreparedStatement psUpdateFragmentNode = null;
1992: PreparedStatement psUpdateFragmentRestriction = null;
1993: PreparedStatement psDeleteFragmentNode = null;
1994: PreparedStatement psDeleteFragmentRestriction = null;
1995:
1996: ALFragment currentFragment = null;
1997:
1998: // If the fragment is not new, a smart-update will be performed
1999: if (!isNewFragment) {
2000:
2001: currentFragment = (ALFragment) getFragment(fragmentId);
2002:
2003: // Build a set of all the fragment node ids of the persisted fragment
2004: for (Enumeration nodeIds = currentFragment
2005: .getNodeIds(); nodeIds.hasMoreElements();) {
2006:
2007: String strNodeId = (String) nodeIds
2008: .nextElement();
2009: int nodeId = CommonUtils.parseInt(strNodeId);
2010:
2011: // Exclude root folder nodes and lost folder nodes
2012: if (!strNodeId
2013: .equals(IALFolderDescription.ROOT_FOLDER_ID)
2014: && !strNodeId
2015: .equals(IALFolderDescription.LOST_FOLDER_ID)) {
2016:
2017: currentNodeIds.add(strNodeId);
2018: }
2019: }
2020:
2021: psUpdateFragmentNode = con
2022: .prepareStatement(FRAGMENT_UPDATE_SQL);
2023: psUpdateFragmentRestriction = con
2024: .prepareStatement(FRAGMENT_RESTRICTION_UPDATE_SQL);
2025: }
2026:
2027: ALFolder rootNode = layout.getLayoutFolder(layout
2028: .getRootId());
2029: String fragmentRootId = rootNode.getFirstChildNodeId();
2030:
2031: RDBMServices.setAutoCommit(con, false); // May speed things up, can't hurt
2032:
2033: // Check if the fragment is new
2034: if (isNewFragment) {
2035:
2036: String sqlInsert = "INSERT INTO UP_OWNER_FRAGMENT (FRAGMENT_ID,FRAGMENT_ROOT_ID,OWNER_ID,FRAGMENT_NAME,FRAGMENT_DESCRIPTION,PUSHED_FRAGMENT) "
2037: + "VALUES (?,?,?,?,?,?)";
2038: PreparedStatement ps = con
2039: .prepareStatement(sqlInsert);
2040: ps.setInt(1, CommonUtils.parseInt(fragmentId));
2041: if (fragmentRootId != null)
2042: ps.setInt(2, CommonUtils
2043: .parseInt(fragmentRootId));
2044: else
2045: ps.setNull(2, Types.INTEGER);
2046: ps.setInt(3, userId);
2047: ps.setString(4, layout.getName());
2048: ps.setString(5, layout.getDescription());
2049: ps.setString(6, (layout.isPushedFragment()) ? "Y"
2050: : "N");
2051: ps.executeUpdate();
2052: ps.close();
2053: } else {
2054:
2055: String sqlUpdate = "UPDATE UP_OWNER_FRAGMENT SET FRAGMENT_NAME=?,FRAGMENT_DESCRIPTION=?,PUSHED_FRAGMENT=?,FRAGMENT_ROOT_ID=? WHERE OWNER_ID=? AND FRAGMENT_ID=?";
2056: PreparedStatement ps = con
2057: .prepareStatement(sqlUpdate);
2058: ps.setString(1, layout.getName());
2059: ps.setString(2, layout.getDescription());
2060: ps.setString(3, (layout.isPushedFragment()) ? "Y"
2061: : "N");
2062: if (fragmentRootId != null)
2063: ps.setInt(4, CommonUtils
2064: .parseInt(fragmentRootId));
2065: else
2066: ps.setNull(4, Types.INTEGER);
2067: ps.setInt(5, userId);
2068: ps.setInt(6, CommonUtils.parseInt(fragmentId));
2069: ps.executeUpdate();
2070: ps.close();
2071: }
2072:
2073: // The loop for all the nodes from the layout
2074: for (Enumeration nodeIds = layout.getNodeIds(); nodeIds
2075: .hasMoreElements();) {
2076: String strNodeId = nodeIds.nextElement().toString();
2077:
2078: newNodeIds.add(strNodeId);
2079:
2080: if (!strNodeId
2081: .equals(IALFolderDescription.ROOT_FOLDER_ID)
2082: && !strNodeId
2083: .equals(IALFolderDescription.LOST_FOLDER_ID)) {
2084:
2085: ALNode node = layout.getNode(strNodeId);
2086: int nodeId = CommonUtils.parseInt(node.getId());
2087:
2088: // Setting the fragment ID
2089: ((IALNodeDescription) node.getNodeDescription())
2090: .setFragmentId(fragmentId);
2091:
2092: int fragmentNodeId = CommonUtils.parseInt(node
2093: .getFragmentNodeId());
2094: String strfragmentNodeId = Integer
2095: .toString(fragmentNodeId);
2096:
2097: boolean isFolder = (node.getNodeType() == IUserLayoutNodeDescription.FOLDER);
2098:
2099: if (CommonUtils.parseInt(node.getFragmentId()) > 0
2100: && fragmentNodeId <= 0) {
2101:
2102: // if the fragment is new or the fragment node id is new then add the fragment node
2103: if (isNewFragment
2104: || !currentNodeIds
2105: .contains(strNodeId)) {
2106: addUserLayoutNode(userId, -1, node,
2107: psAddFragmentNode,
2108: psAddFragmentRestriction, null,
2109: null, stmt);
2110: } else {
2111: // Update the existing fragment node
2112: updateUserLayoutNode(userId, -1, node,
2113: psUpdateFragmentNode,
2114: psUpdateFragmentRestriction,
2115: null, null);
2116:
2117: }
2118: }
2119:
2120: if (userPrefs != null) {
2121: Map attributeNametoValues = new HashMap();
2122: StructureStylesheetUserPreferences ssup = userPrefs
2123: .getStructureStylesheetUserPreferences();
2124: for (Enumeration attre = ssup
2125: .getFolderAttributeNames(); attre
2126: .hasMoreElements();) {
2127: String pName = (String) attre
2128: .nextElement();
2129: String pValue = ssup
2130: .getDefinedFolderAttributeValue(
2131: strNodeId, pName);
2132: if (pValue != null) {
2133: attributeNametoValues.put(pName,
2134: pValue);
2135: }
2136: }
2137: if (!attributeNametoValues.isEmpty()) {
2138: nodeAttributeService
2139: .storeFragmentNodeAttributes(
2140: Integer
2141: .parseInt(fragmentId),
2142: Integer
2143: .parseInt(strNodeId),
2144: attributeNametoValues);
2145: }
2146: }
2147:
2148: } // End if
2149: } // End for
2150:
2151: if (stmt != null)
2152: stmt.close();
2153:
2154: // If this is not a new fragment, check for deleted fragment nodes
2155: if (!isNewFragment) {
2156:
2157: psDeleteFragmentNode = con
2158: .prepareStatement("DELETE FROM UP_FRAGMENTS WHERE FRAGMENT_ID=? AND NODE_ID=?");
2159: psDeleteFragmentRestriction = con
2160: .prepareStatement("DELETE FROM UP_FRAGMENT_RESTRICTIONS WHERE FRAGMENT_ID=? AND NODE_ID=?");
2161:
2162: Iterator currentFragmentNodes = currentNodeIds
2163: .iterator();
2164: int intFragmentId = CommonUtils
2165: .parseInt(fragmentId);
2166:
2167: while (currentFragmentNodes.hasNext()) {
2168:
2169: String currentId = (String) currentFragmentNodes
2170: .next();
2171:
2172: // Delete all nodes that dont exist in the new layout
2173: if (!newNodeIds.contains(currentId)) {
2174:
2175: int nodeId = CommonUtils
2176: .parseInt(currentId);
2177: psDeleteFragmentNode.setInt(1,
2178: intFragmentId);
2179: psDeleteFragmentNode.setInt(2, nodeId);
2180: psDeleteFragmentNode.executeUpdate();
2181: psDeleteFragmentRestriction.setInt(1,
2182: intFragmentId);
2183: psDeleteFragmentRestriction.setInt(2,
2184: nodeId);
2185: psDeleteFragmentRestriction.executeUpdate();
2186: }
2187: }
2188: }
2189:
2190: if (psAddFragmentNode != null)
2191: psAddFragmentNode.close();
2192: if (psAddFragmentRestriction != null)
2193: psAddFragmentRestriction.close();
2194: if (psUpdateFragmentNode != null)
2195: psUpdateFragmentNode.close();
2196: if (psUpdateFragmentRestriction != null)
2197: psUpdateFragmentRestriction.close();
2198: if (psDeleteFragmentNode != null)
2199: psDeleteFragmentNode.close();
2200: if (psDeleteFragmentRestriction != null)
2201: psDeleteFragmentRestriction.close();
2202:
2203: // Commit all the changes
2204: RDBMServices.commit(con);
2205: RDBMServices.setAutoCommit(con, true);
2206:
2207: String sql = "SELECT chld_node_id from up_fragments where node_id = 1 and fragment_id="
2208: + fragmentId;
2209: stmt = con.createStatement();
2210: rs = stmt.executeQuery(sql);
2211:
2212: if (rs.next()) {
2213: int childId = rs.getInt(1);
2214: }
2215:
2216: rs.close();
2217: rs = null;
2218: stmt.close();
2219: stmt = null;
2220:
2221: // Close the connection
2222: if (con != null)
2223: con.close();
2224:
2225: } catch (Exception e) {
2226: log.error(e, e);
2227: try {
2228: RDBMServices.rollback(con);
2229: } catch (Exception e1) {
2230: //ignore
2231: }
2232: throw new PortalException(e);
2233: }
2234: }
2235: }
2236:
2237: /**
2238: * Deletes the layout fragment
2239: * @param person an <code>IPerson</code> object specifying the user
2240: * @param fragmentId a fragment ID
2241: * @exception PortalException if an error occurs
2242: */
2243: public void deleteFragment(IPerson person, String fragmentId)
2244: throws PortalException {
2245:
2246: int userId = person.getID();
2247: Connection con = RDBMServices.getConnection();
2248:
2249: try {
2250:
2251: RDBMServices.setAutoCommit(con, false); // May speed things up, can't hurt
2252:
2253: Statement stmt = con.createStatement();
2254: boolean isOwner = false;
2255: // Check if the user was an owner
2256: ResultSet rs = stmt
2257: .executeQuery("SELECT OWNER_ID FROM UP_OWNER_FRAGMENT WHERE FRAGMENT_ID="
2258: + fragmentId);
2259: if (rs.next()) {
2260: if (rs.getInt(1) == userId)
2261: isOwner = true;
2262: }
2263: if (rs != null)
2264: rs.close();
2265:
2266: if (!isOwner)
2267: throw new PortalException("The user " + userId
2268: + " is not an owner of the fragment with ID="
2269: + fragmentId);
2270:
2271: stmt
2272: .executeUpdate("DELETE FROM UP_FRAGMENT_RESTRICTIONS WHERE FRAGMENT_ID="
2273: + fragmentId);
2274: stmt
2275: .executeUpdate("DELETE FROM UP_FRAGMENT_PARAM WHERE FRAGMENT_ID="
2276: + fragmentId);
2277: stmt
2278: .executeUpdate("DELETE FROM UP_GROUP_FRAGMENT WHERE FRAGMENT_ID="
2279: + fragmentId);
2280: stmt
2281: .executeUpdate("DELETE FROM UP_FRAGMENTS WHERE FRAGMENT_ID="
2282: + fragmentId);
2283:
2284: if (stmt != null)
2285: stmt.close();
2286:
2287: String sqlUpdate = "DELETE FROM UP_OWNER_FRAGMENT WHERE OWNER_ID=? AND FRAGMENT_ID=?";
2288: PreparedStatement ps = con.prepareStatement(sqlUpdate);
2289: ps.setInt(1, userId);
2290: ps.setInt(2, CommonUtils.parseInt(fragmentId));
2291: ps.executeUpdate();
2292: ps.close();
2293:
2294: // Commit all the changes
2295: RDBMServices.commit(con);
2296:
2297: } catch (Exception e) {
2298: log.error(e, e);
2299: try {
2300: RDBMServices.rollback(con);
2301: } catch (SQLException e1) {
2302: // ignore
2303: }
2304: throw new PortalException(e);
2305: } finally {
2306: // Close the connection
2307: RDBMServices.releaseConnection(con);
2308: }
2309:
2310: }
2311:
2312: /**
2313: * Returns the user layout internal representation.
2314: * @param person an <code>IPerson</code> object specifying the user
2315: * @param profile a user profile for which the layout is being stored
2316: * @return a <code>IAggregatedLayout</code> object containing the internal representation of the user layout
2317: * @exception PortalException if an error occurs
2318: */
2319: public IAggregatedLayout getAggregatedLayout(IPerson person,
2320: UserProfile profile) throws PortalException {
2321: int userId = person.getID();
2322: int realUserId = userId;
2323: ResultSet rs;
2324:
2325: Connection con = null;
2326: AggregatedLayout layout = null;
2327: Hashtable layoutData = null;
2328: ALFolder rootNode = new ALFolder();
2329: ALFolder lostFolder = ALFolder.createLostFolder();
2330: //PreparedStatement psRestrLayout = null, psRestrFragment = null;
2331: Hashtable pushFragmentRoots = null;
2332: String pushFragmentIds = null;
2333:
2334: try {
2335:
2336: EntityIdentifier personIdentifier = person
2337: .getEntityIdentifier();
2338: IGroupMember groupPerson = GroupService
2339: .getGroupMember(personIdentifier);
2340:
2341: con = RDBMServices.getConnection();
2342: RDBMServices.setAutoCommit(con, false);
2343:
2344: layoutData = new Hashtable(50);
2345:
2346: Iterator containingGroups = groupPerson
2347: .getAllContainingGroups();
2348:
2349: if (containingGroups.hasNext()) {
2350: // Getting push-fragments based on a group key parameter
2351: PreparedStatement psGroups = con
2352: .prepareStatement("SELECT UOF.FRAGMENT_ID, UOF.FRAGMENT_ROOT_ID FROM UP_GROUP_FRAGMENT UPG, UP_OWNER_FRAGMENT UOF "
2353: + "WHERE UPG.GROUP_KEY=? AND UPG.FRAGMENT_ID = UOF.FRAGMENT_ID AND UOF.PUSHED_FRAGMENT='Y'");
2354:
2355: pushFragmentRoots = new Hashtable();
2356: while (containingGroups.hasNext()) {
2357: IEntityGroup entityGroup = (IEntityGroup) containingGroups
2358: .next();
2359: psGroups.setString(1, entityGroup.getKey());
2360: ResultSet rsGroups = psGroups.executeQuery();
2361: if (rsGroups.next()) {
2362: int fragmentId = rsGroups.getInt(1);
2363: if (pushFragmentIds == null)
2364: pushFragmentIds = fragmentId + "";
2365: else
2366: pushFragmentIds += "," + fragmentId;
2367: pushFragmentRoots.put("" + fragmentId, rsGroups
2368: .getInt(2)
2369: + "");
2370: }
2371: while (rsGroups.next()) {
2372: int fragmentId = rsGroups.getInt(1);
2373: pushFragmentIds += "," + fragmentId;
2374: pushFragmentRoots.put("" + fragmentId, rsGroups
2375: .getInt(2)
2376: + "");
2377: }
2378: if (rsGroups != null)
2379: rsGroups.close();
2380: }
2381:
2382: if (psGroups != null)
2383: psGroups.close();
2384: } // end if hasNext()
2385:
2386: Statement stmt = con.createStatement();
2387: // A separate statement is needed so as not to interfere with ResultSet
2388: // of statements used for queries
2389: Statement insertStmt = con.createStatement();
2390:
2391: try {
2392: long startTime = System.currentTimeMillis();
2393: // eventually, we need to fix template layout implementations so you can just do this:
2394: // int layoutId=profile.getLayoutId();
2395: // but for now:
2396: String subSelectString = "SELECT LAYOUT_ID FROM UP_USER_PROFILE WHERE USER_ID="
2397: + userId
2398: + " AND PROFILE_ID="
2399: + profile.getProfileId();
2400: if (log.isDebugEnabled())
2401: log
2402: .debug("AggregatedUserLayoutStore::getUserLayout(): "
2403: + subSelectString);
2404: int layoutId = -1;
2405: rs = stmt.executeQuery(subSelectString);
2406: try {
2407: if (rs.next()) {
2408: layoutId = rs.getInt(1);
2409: if (rs.wasNull())
2410: layoutId = -1;
2411: }
2412: } finally {
2413: rs.close();
2414: }
2415:
2416: if (layoutId < 0) { // First time, grab the default layout for this user
2417: String sQuery = "SELECT USER_DFLT_USR_ID, USER_DFLT_LAY_ID FROM UP_USER WHERE USER_ID="
2418: + userId;
2419: if (log.isDebugEnabled())
2420: log
2421: .debug("AggregatedUserLayoutStore::getUserLayout(): "
2422: + sQuery);
2423: rs = stmt.executeQuery(sQuery);
2424: try {
2425: if (rs.next()) {
2426: userId = rs.getInt(1);
2427: layoutId = rs.getInt(2);
2428: }
2429: } finally {
2430: rs.close();
2431: }
2432:
2433: // Make sure the next struct id is set in case the user adds a channel
2434: sQuery = "SELECT NEXT_STRUCT_ID FROM UP_USER WHERE USER_ID="
2435: + userId;
2436: if (log.isDebugEnabled())
2437: log
2438: .debug("AggregatedUserLayoutStore::getUserLayout(): "
2439: + sQuery);
2440: int nextStructId = 0;
2441: rs = stmt.executeQuery(sQuery);
2442: try {
2443: if (rs.next())
2444: nextStructId = rs.getInt(1);
2445: } finally {
2446: rs.close();
2447: }
2448: sQuery = "UPDATE UP_USER SET NEXT_STRUCT_ID="
2449: + nextStructId + " WHERE USER_ID="
2450: + realUserId;
2451: if (log.isDebugEnabled())
2452: log
2453: .debug("AggregatedUserLayoutStore::getUserLayout(): "
2454: + sQuery);
2455: stmt.executeUpdate(sQuery);
2456:
2457: /*
2458: sQuery = "DELETE FROM UP_SS_USER_ATTS WHERE USER_ID=" + realUserId;
2459: if (log.isDebugEnabled())
2460: log.debug("AggregatedUserLayoutStore::getUserLayout(): " + sQuery);
2461: stmt.executeUpdate(sQuery);
2462:
2463: sQuery = " SELECT "+realUserId+", PROFILE_ID, SS_ID, SS_TYPE, STRUCT_ID, PARAM_NAME, PARAM_TYPE, PARAM_VAL "+
2464: " FROM UP_SS_USER_ATTS WHERE USER_ID="+userId;
2465: rs = stmt.executeQuery(sQuery);
2466:
2467:
2468: while (rs.next()) {
2469: String Insert = "INSERT INTO UP_SS_USER_ATTS (USER_ID, PROFILE_ID, SS_ID, SS_TYPE, STRUCT_ID, PARAM_NAME, PARAM_TYPE, PARAM_VAL) " +
2470: "VALUES("+realUserId+","+
2471: rs.getInt("PROFILE_ID")+","+
2472: rs.getInt("SS_ID")+"," +
2473: rs.getInt("SS_TYPE")+"," +
2474: rs.getString("STRUCT_ID")+"," +
2475: "'"+rs.getString("PARAM_NAME")+"'," +
2476: rs.getInt("PARAM_TYPE")+"," +
2477: "'"+rs.getString("PARAM_VAL")+"')";
2478:
2479: if (log.isDebugEnabled())
2480: log.debug("AggregatedUserLayoutStore::getUserLayout(): " + Insert);
2481: insertStmt.executeUpdate(Insert);
2482: }
2483: */
2484:
2485: syncUserAttributes(con, realUserId, userId);
2486:
2487: // Close Result Set
2488: if (rs != null)
2489: rs.close();
2490:
2491: RDBMServices.commit(con); // Make sure it appears in the store
2492: } // end if layoutID == null
2493:
2494: int firstStructId = -1;
2495: String sQuery = "SELECT INIT_NODE_ID FROM UP_USER_LAYOUT_AGGR WHERE USER_ID="
2496: + userId + " AND LAYOUT_ID = " + layoutId;
2497: if (log.isDebugEnabled())
2498: log
2499: .debug("AggregatedUserLayoutStore::getUserLayout(): "
2500: + sQuery);
2501: rs = stmt.executeQuery(sQuery);
2502: try {
2503: if (rs.next())
2504: firstStructId = rs.getInt(1);
2505: else {
2506: if (userId == realUserId) {
2507: // read the template userid
2508: String tQuery = "SELECT USER_DFLT_USR_ID, USER_DFLT_LAY_ID FROM UP_USER WHERE USER_ID="
2509: + userId;
2510: log
2511: .debug("AggregatedUserLayoutStore::getAggregatedLayout(): "
2512: + tQuery);
2513: rs = stmt.executeQuery(tQuery);
2514: try {
2515: if (rs.next()) {
2516: userId = rs.getInt(1);
2517: layoutId = rs.getInt(2);
2518: }
2519: } finally {
2520: rs.close();
2521: }
2522: if (userId != realUserId) {
2523: // retry reading the structid -- now from the template user
2524: sQuery = "SELECT INIT_NODE_ID FROM UP_USER_LAYOUT_AGGR WHERE USER_ID="
2525: + userId
2526: + " AND LAYOUT_ID = "
2527: + layoutId;
2528: log
2529: .debug("AggregatedUserLayoutStore::getAggregatedLayout(): "
2530: + sQuery);
2531: rs = stmt.executeQuery(sQuery);
2532: try {
2533: if (rs.next())
2534: firstStructId = rs.getInt(1);
2535: } finally {
2536: rs.close();
2537: }
2538: }
2539: }
2540: if (firstStructId < 0)
2541: throw new PortalException(
2542: "AggregatedUserLayoutStore::getAggregatedLayout(): No INIT_NODE_ID in UP_USER_LAYOUT_AGGR for "
2543: + userId
2544: + " and LAYOUT_ID "
2545: + layoutId);
2546: }
2547: } finally {
2548: rs.close();
2549: }
2550:
2551: // we have to delete all the records from up_layout_struct_aggr table related to the lost nodes.
2552: // do this only if we are not deferring to the template. (once in a great while 'we' will BE the template)
2553: if (userId == realUserId) {
2554: /* end */
2555: log.debug("deleting lost nodes because userId:"
2556: + userId + "== realUserId:" + realUserId);
2557: stmt
2558: .executeUpdate("DELETE FROM UP_LAYOUT_STRUCT_AGGR WHERE USER_ID="
2559: + userId
2560: + " AND LAYOUT_ID="
2561: + layoutId
2562: + " AND PRNT_NODE_ID="
2563: + LOST_FOLDER_ID);
2564: } else {
2565: log.debug("not deleting lost nodes because userId:"
2566: + userId + "!= realUserId:" + realUserId);
2567: }
2568:
2569: // Instantiating the layout and setting the layout ID
2570: layout = new AggregatedLayout(layoutId + "");
2571:
2572: String restrLayoutSQL = "SELECT RESTRICTION_NAME, RESTRICTION_VALUE, RESTRICTION_TREE_PATH FROM UP_LAYOUT_RESTRICTIONS "
2573: + "WHERE LAYOUT_ID="
2574: + layoutId
2575: + " AND USER_ID=" + userId + " AND NODE_ID=?";
2576: String restrFragmentSQL = "SELECT RESTRICTION_NAME, RESTRICTION_VALUE, RESTRICTION_TREE_PATH FROM UP_FRAGMENT_RESTRICTIONS "
2577: + "WHERE FRAGMENT_ID=? AND NODE_ID=?";
2578:
2579: // Creating a root folder
2580: rootNode = ALFolder.createRootFolder();
2581: // Setting the first layout node ID to the root folder
2582: rootNode.setFirstChildNodeId(firstStructId + "");
2583:
2584: // Putting the root node
2585: layoutData.put(IALFolderDescription.ROOT_FOLDER_ID,
2586: rootNode);
2587: // Putting the lost folder
2588: layoutData.put(IALFolderDescription.LOST_FOLDER_ID,
2589: lostFolder);
2590:
2591: // layout query
2592: String sqlLayout = "SELECT ULS.NODE_ID,ULS.NEXT_NODE_ID,ULS.CHLD_NODE_ID,ULS.PREV_NODE_ID,ULS.PRNT_NODE_ID,ULS.CHAN_ID,ULS.NAME,ULS.TYPE,ULS.HIDDEN,"
2593: + "ULS.UNREMOVABLE,ULS.IMMUTABLE,ULS.PRIORITY,ULS.FRAGMENT_ID,ULS.FRAGMENT_NODE_ID";
2594: sqlLayout += " FROM UP_LAYOUT_STRUCT_AGGR ULS WHERE ";
2595: sqlLayout += " ULS.USER_ID=" + userId
2596: + " AND ULS.LAYOUT_ID=" + layoutId;
2597:
2598: log.debug(sqlLayout);
2599:
2600: // The query for getting information of the fragments
2601: String sqlFragment = "SELECT DISTINCT UF.NODE_ID,UF.NEXT_NODE_ID,UF.CHLD_NODE_ID,UF.PREV_NODE_ID,UF.PRNT_NODE_ID,UF.CHAN_ID,UF.NAME,UF.TYPE,UF.HIDDEN,"
2602: + "UF.UNREMOVABLE,UF.IMMUTABLE,UF.PRIORITY,UF.FRAGMENT_ID ";
2603: sqlFragment += "FROM UP_FRAGMENTS UF, UP_LAYOUT_STRUCT_AGGR ULS ";
2604:
2605: sqlFragment += "WHERE ULS.USER_ID=" + userId
2606: + " AND ULS.FRAGMENT_ID=UF.FRAGMENT_ID ";
2607:
2608: if (pushFragmentIds != null) {
2609: sqlFragment += "UNION ";
2610: sqlFragment += "SELECT DISTINCT UF.NODE_ID,UF.NEXT_NODE_ID,UF.CHLD_NODE_ID,UF.PREV_NODE_ID,UF.PRNT_NODE_ID,UF.CHAN_ID,UF.NAME,UF.TYPE,UF.HIDDEN,"
2611: + "UF.UNREMOVABLE,UF.IMMUTABLE,UF.PRIORITY,UF.FRAGMENT_ID ";
2612: sqlFragment += "FROM UP_FRAGMENTS UF ";
2613: sqlFragment += "WHERE UF.FRAGMENT_ID IN ("
2614: + pushFragmentIds + ")";
2615: }
2616: log.debug(sqlFragment);
2617:
2618: // The hashtable object containing the fragment nodes that are next to the user layout nodes
2619: Hashtable fragmentNodes = new Hashtable();
2620: // Set to contain a list of completed fragments.
2621: Set finishedFragmentNodes = new HashSet();
2622:
2623: int count = 0;
2624: for (String sql = sqlLayout; count < 2; sql = sqlFragment, count++) {
2625:
2626: List chanIds = Collections
2627: .synchronizedList(new ArrayList());
2628: StringBuffer structParms = new StringBuffer();
2629:
2630: rs = stmt.executeQuery(sql);
2631:
2632: try {
2633: int lastStructId = 0;
2634: String sepChar = "";
2635: if (rs.next()) {
2636: int structId = rs.getInt(1);
2637: readLayout: while (true) {
2638:
2639: if (DEBUG > 1)
2640: System.err
2641: .println("Found layout structureID "
2642: + structId);
2643:
2644: int nextId = rs.getInt(2);
2645: int childId = rs.getInt(3);
2646: int prevId = rs.getInt(4);
2647: int prntId = rs.getInt(5);
2648: int chanId = rs.getInt(6);
2649: int fragmentId = rs.getInt(13);
2650: int fragmentNodeId = (sql
2651: .equals(sqlLayout)) ? rs
2652: .getInt(14) : 0;
2653:
2654: IALNodeDescription nodeDesc = null;
2655: // Trying to get the node if it already exists
2656: ALNode node;
2657: String childIdStr = null;
2658: if (chanId <= 0) {
2659: node = new ALFolder();
2660: IALFolderDescription folderDesc = new ALFolderDescription();
2661: // If children exist in the folder
2662: if (childId > 0)
2663: childIdStr = (fragmentId > 0 && fragmentNodeId <= 0) ? (fragmentId
2664: + NODE_SEPARATOR + childId)
2665: : (childId + "");
2666: ((ALFolder) node)
2667: .setFirstChildNodeId(childIdStr);
2668: String type = rs.getString(8);
2669: int intType;
2670: if ("header".equalsIgnoreCase(type))
2671: intType = UserLayoutFolderDescription.HEADER_TYPE;
2672: else if ("footer"
2673: .equalsIgnoreCase(type))
2674: intType = UserLayoutFolderDescription.FOOTER_TYPE;
2675: else
2676: intType = UserLayoutFolderDescription.REGULAR_TYPE;
2677:
2678: folderDesc.setFolderType(intType);
2679: nodeDesc = folderDesc;
2680:
2681: // Folder nodes can have attributes
2682: // (width)
2683:
2684: Map nodeAttributes = this .nodeAttributeService
2685: .attributesForFragmentNode(
2686: fragmentId,
2687: structId);
2688: node.putAttributes(nodeAttributes);
2689:
2690: } else {
2691: node = new ALChannel();
2692: ALChannelDescription channelDesc = new ALChannelDescription();
2693: channelDesc.setChannelPublishId(rs
2694: .getString(6));
2695: nodeDesc = channelDesc;
2696: }
2697:
2698: // Setting node description attributes
2699: if (node.getNodeType() == IUserLayoutNodeDescription.FOLDER)
2700: nodeDesc.setName(rs.getString(7));
2701: nodeDesc.setHidden(("Y"
2702: .equalsIgnoreCase(rs
2703: .getString(9)) ? true
2704: : false));
2705: if (fragmentId > 0)
2706: nodeDesc.setImmutable(true);
2707: else
2708: nodeDesc
2709: .setImmutable(("Y"
2710: .equalsIgnoreCase(rs
2711: .getString(11)) ? true
2712: : false));
2713:
2714: if (pushFragmentRoots
2715: .containsKey(Integer
2716: .toString(fragmentId))) {
2717: nodeDesc.setUnremovable(true);
2718: } else {
2719: nodeDesc
2720: .setUnremovable(("Y"
2721: .equalsIgnoreCase(rs
2722: .getString(10)) ? true
2723: : false));
2724: }
2725:
2726: node.setPriority(rs.getInt(12));
2727:
2728: nodeDesc
2729: .setFragmentId((fragmentId > 0) ? fragmentId
2730: + ""
2731: : null);
2732:
2733: if (sql.equals(sqlLayout)) {
2734: nodeDesc
2735: .setFragmentNodeId((fragmentNodeId > 0) ? fragmentNodeId
2736: + ""
2737: : null);
2738: }
2739:
2740: // Setting the node id
2741: if (fragmentId > 0
2742: && fragmentNodeId <= 0)
2743: nodeDesc
2744: .setId(fragmentId
2745: + NODE_SEPARATOR
2746: + structId);
2747: else
2748: nodeDesc
2749: .setId((structId != LOST_FOLDER_ID) ? (structId + "")
2750: : IALFolderDescription.LOST_FOLDER_ID);
2751:
2752: // Setting the next node id
2753: if (nextId != 0) {
2754: String nextIdStr = (fragmentId > 0 && fragmentNodeId <= 0) ? (fragmentId
2755: + NODE_SEPARATOR + nextId)
2756: : (nextId + "");
2757: node.setNextNodeId(nextIdStr);
2758: }
2759:
2760: String parentId;
2761: switch (prntId) {
2762: case 0:
2763: parentId = IALFolderDescription.ROOT_FOLDER_ID;
2764: break;
2765: case LOST_FOLDER_ID:
2766: parentId = IALFolderDescription.LOST_FOLDER_ID;
2767: break;
2768: default:
2769: parentId = (fragmentId > 0 && fragmentNodeId <= 0) ? (fragmentId
2770: + NODE_SEPARATOR + prntId)
2771: : (prntId + "");
2772:
2773: }
2774:
2775: // Setting up the parent id
2776: node.setParentNodeId(parentId);
2777:
2778: // Setting the previous node id
2779: if (prevId != 0) {
2780: String prevIdStr = (fragmentId > 0 && fragmentNodeId <= 0) ? (fragmentId
2781: + NODE_SEPARATOR + prevId)
2782: : (prevId + "");
2783: node.setPreviousNodeId(prevIdStr);
2784: }
2785:
2786: lastStructId = structId;
2787:
2788: String fragmentNodeIdStr = nodeDesc
2789: .getFragmentNodeId();
2790: String fragmentIdStr = nodeDesc
2791: .getFragmentId();
2792: String key = fragmentId
2793: + NODE_SEPARATOR + structId;
2794:
2795: // Putting the node into the layout hashtable with an appropriate key
2796: node.setNodeDescription(nodeDesc);
2797: if (fragmentNodeIdStr != null) {
2798: fragmentNodes.put(fragmentIdStr
2799: + NODE_SEPARATOR
2800: + fragmentNodeIdStr, node);
2801: } else {
2802: if (fragmentIdStr != null
2803: && fragmentNodes
2804: .containsKey(key)) {
2805: ALNode fragNode = (ALNode) fragmentNodes
2806: .get(key);
2807: nodeDesc
2808: .setId(fragNode.getId());
2809: nodeDesc
2810: .setFragmentNodeId(fragNode
2811: .getFragmentNodeId());
2812: nodeDesc.setImmutable(true);
2813: fragNode
2814: .setNodeDescription(nodeDesc);
2815: if (fragNode.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
2816: ((ALFolder) fragNode)
2817: .setFirstChildNodeId(childIdStr);
2818: }
2819: layoutData.put(
2820: nodeDesc.getId(),
2821: fragNode);
2822: // Add it to the list of completed fragment nodes
2823: finishedFragmentNodes.add(key);
2824: } else
2825: layoutData.put(
2826: nodeDesc.getId(), node);
2827: }
2828:
2829: // If there is a channel we need to get its parameters
2830: IALChannelDescription channelDesc = null;
2831: if (node.getNodeType() == IUserLayoutNodeDescription.CHANNEL) {
2832: channelDesc = (IALChannelDescription) nodeDesc;
2833: chanIds.add(nodeDesc.getId());
2834: }
2835:
2836: // getting restrictions for the nodes
2837: PreparedStatement psRestr = null;
2838: if (sql.equals(sqlLayout)
2839: && fragmentNodeId <= 0) {
2840: psRestr = con
2841: .prepareStatement(restrLayoutSQL);
2842: psRestr.setInt(1, structId);
2843: } else {
2844: psRestr = con
2845: .prepareStatement(restrFragmentSQL);
2846: psRestr.setInt(1, fragmentId);
2847: psRestr
2848: .setInt(
2849: 2,
2850: (fragmentNodeId > 0) ? fragmentNodeId
2851: : structId);
2852: }
2853: ResultSet rsRestr = psRestr
2854: .executeQuery();
2855: while (rsRestr.next()) {
2856: String restrName = rsRestr
2857: .getString(1);
2858: String restrExp = rsRestr
2859: .getString(2);
2860: String restrPath = rsRestr
2861: .getString(3);
2862: if (restrPath == null
2863: || restrPath.trim()
2864: .length() == 0)
2865: restrPath = IUserLayoutRestriction.LOCAL_RESTRICTION_PATH;
2866: IUserLayoutRestriction restriction = UserLayoutRestrictionFactory
2867: .createRestriction(
2868: restrName,
2869: restrExp, restrPath);
2870: nodeDesc
2871: .addRestriction(restriction);
2872: }
2873: rsRestr.close();
2874: if (psRestr != null)
2875: psRestr.close();
2876:
2877: int index = (sql.equals(sqlLayout)) ? 15
2878: : 14;
2879:
2880: // Adding the channel ID to the String buffer
2881: if (node.getNodeType() == IUserLayoutNodeDescription.CHANNEL) {
2882: structParms
2883: .append(sepChar + chanId);
2884: sepChar = ",";
2885: }
2886:
2887: if (rs.next()) {
2888: structId = rs.getInt(1);
2889: if (rs.wasNull()) {
2890: structId = 0;
2891: }
2892: } else {
2893: break readLayout;
2894: }
2895:
2896: // Setting up the priority values based on the appropriate priority restrictions
2897: PriorityRestriction priorityRestriction = AggregatedLayoutManager
2898: .getPriorityRestriction(node);
2899: if (priorityRestriction != null) {
2900: int priority = node.getPriority();
2901: int[] range = priorityRestriction
2902: .getRange();
2903:
2904: int newPriority = priority;
2905: if (range[0] > priority)
2906: newPriority = range[0];
2907: else if (range[1] < priority)
2908: newPriority = range[1];
2909:
2910: // Changing the node priority if it's been changed
2911: if (newPriority != priority)
2912: node.setPriority(newPriority);
2913: }
2914:
2915: } // while
2916: }
2917: } finally {
2918: rs.close();
2919: }
2920:
2921: // We have to retrieve the channel defition after the layout structure
2922: // since retrieving the channel data from the DB may interfere with the
2923: // layout structure ResultSet (in other words, Oracle is a pain to program for)
2924: if (chanIds.size() > 0) {
2925:
2926: for (int i = 0; i < chanIds.size(); i++) {
2927:
2928: String key = (String) chanIds.get(i);
2929:
2930: ALNode node = (ALNode) layoutData.get(key);
2931:
2932: fillChannelDescription((IALChannelDescription) node
2933: .getNodeDescription());
2934:
2935: }
2936:
2937: chanIds.clear();
2938: }
2939:
2940: if (structParms.length() > 0) { // Pick up structure parameters
2941: String paramSql = "SELECT STRUCT_ID, STRUCT_PARM_NM,STRUCT_PARM_VAL FROM UP_LAYOUT_PARAM WHERE USER_ID="
2942: + userId
2943: + " AND LAYOUT_ID="
2944: + layoutId
2945: + " AND STRUCT_ID IN ("
2946: + structParms.toString()
2947: + ") ORDER BY STRUCT_ID";
2948: if (log.isDebugEnabled())
2949: log
2950: .debug("AggregatedUserLayoutStore::getUserLayout(): "
2951: + paramSql);
2952:
2953: // Adding this to prevent the error "closed statement" in Oracle
2954: Statement st = con.createStatement();
2955:
2956: rs = st.executeQuery(paramSql);
2957:
2958: try {
2959: if (rs.next()) {
2960:
2961: int structId = rs.getInt(1);
2962: readParm: while (true) {
2963:
2964: ALNode node = (ALNode) layoutData
2965: .get(structId + "");
2966: if (node != null) {
2967: IALChannelDescription channelDesc = (IALChannelDescription) node
2968: .getNodeDescription();
2969: int lastStructId = structId;
2970: do {
2971:
2972: String name = rs
2973: .getString(2);
2974: String value = rs
2975: .getString(3);
2976: channelDesc
2977: .setParameterValue(
2978: name, value);
2979: if (!rs.next()) {
2980: break readParm;
2981: }
2982: } while ((structId = rs
2983: .getInt(1)) == lastStructId);
2984:
2985: } else
2986: break readParm; // if else
2987: }
2988: }
2989: } finally {
2990: rs.close();
2991: st.close();
2992: }
2993: }
2994:
2995: } // End of for
2996:
2997: // Clean up lost fragments
2998: Set incompleteFragments = new HashSet(fragmentNodes
2999: .keySet());
3000: incompleteFragments.removeAll(finishedFragmentNodes);
3001: if (!incompleteFragments.isEmpty()) {
3002: // Remap by fragNode id, to allow for lost folder management of
3003: // multiple lost fragments.
3004: Hashtable lostFragmentNodes = new Hashtable();
3005: for (Iterator it = incompleteFragments.iterator(); it
3006: .hasNext();) {
3007: String key = (String) it.next();
3008: ALNode fragNode = (ALNode) fragmentNodes
3009: .get(key);
3010: lostFragmentNodes.put(fragNode.getId(),
3011: fragNode);
3012: }
3013:
3014: for (Iterator it = incompleteFragments.iterator(); it
3015: .hasNext();) {
3016: String key = (String) it.next();
3017: ALNode fragNode = (ALNode) fragmentNodes
3018: .get(key);
3019: String nextId = fragNode.getNextNodeId();
3020: String prevId = fragNode.getPreviousNodeId();
3021: String parentId = fragNode.getParentNodeId();
3022:
3023: ALNode prevNode = null;
3024: if (prevId != null) {
3025: prevNode = (ALNode) layoutData.get(prevId);
3026: if (prevNode == null)
3027: prevNode = (ALNode) lostFragmentNodes
3028: .get(prevId);
3029: }
3030:
3031: ALNode nextNode = null;
3032: if (nextId != null) {
3033: nextNode = (ALNode) layoutData.get(nextId);
3034: if (nextNode == null)
3035: nextNode = (ALNode) lostFragmentNodes
3036: .get(nextId);
3037: }
3038:
3039: if (prevNode != null) {
3040: if (nextNode != null) {
3041: nextNode.setPreviousNodeId(prevId);
3042: prevNode.setNextNodeId(nextId);
3043: } else {
3044: prevNode.setNextNodeId(null);
3045: }
3046: } else {
3047: if (nextNode != null) {
3048: nextNode.setPreviousNodeId(null);
3049: }
3050:
3051: // Update parent node, as we are their first child.
3052: ALFolder parentNode = null;
3053: if (parentId != null) {
3054: parentNode = (ALFolder) layoutData
3055: .get(parentId);
3056: if (parentNode != null) {
3057: parentNode
3058: .setFirstChildNodeId((nextNode == null) ? null
3059: : nextId);
3060: }
3061: }
3062: }
3063:
3064: // Remove this node's distinction as a fragment node
3065: // to be reparented.
3066: fragmentNodes.remove(key);
3067:
3068: // Academus-specific: Move node to lost folder to ensure row removal from DB.
3069: fragNode.setNextNodeId(null);
3070: fragNode
3071: .setParentNodeId(IALFolderDescription.LOST_FOLDER_ID);
3072:
3073: ALNode lostNodeSib = null;
3074: for (String nextLostSibId = lostFolder
3075: .getFirstChildNodeId(); nextLostSibId != null;) {
3076: lostNodeSib = (ALNode) layoutData
3077: .get(nextLostSibId);
3078: nextLostSibId = lostNodeSib.getNextNodeId();
3079: }
3080:
3081: if (lostNodeSib != null) {
3082: lostNodeSib.setNextNodeId(fragNode.getId());
3083: fragNode.setPreviousNodeId(lostNodeSib
3084: .getId());
3085: } else {
3086: fragNode.setPreviousNodeId(null);
3087: lostFolder.setFirstChildNodeId(fragNode
3088: .getId());
3089: }
3090:
3091: layoutData.put(fragNode.getId(), fragNode);
3092: // End academus-specific
3093: }
3094: }
3095:
3096: // finding the last node in the sibling line of the root children
3097: ALNode lastNode = null, prevNode = null;
3098: String nextId = rootNode.getFirstChildNodeId();
3099: while (nextId != null) {
3100: lastNode = (ALNode) layoutData.get(nextId);
3101: // If neccessary cleaning the end of tabs sibling line setting the next ID to null of the last tab
3102: if (lastNode == null) {
3103: if (prevNode != null) {
3104: prevNode.setNextNodeId(null);
3105: lastNode = prevNode;
3106: }
3107: break;
3108: }
3109: nextId = lastNode.getNextNodeId();
3110: prevNode = lastNode;
3111: }
3112:
3113: // Binding the push-fragments to the end of the sibling line of the root children
3114: if (pushFragmentRoots != null) {
3115: for (Enumeration fragmentIds = pushFragmentRoots
3116: .keys(); fragmentIds.hasMoreElements();) {
3117: String strFragmentId = fragmentIds
3118: .nextElement().toString();
3119: String strFragmentRootId = pushFragmentRoots
3120: .get(strFragmentId).toString();
3121: String key = strFragmentId + NODE_SEPARATOR
3122: + strFragmentRootId;
3123: ALNode node = (ALNode) layoutData.get(key);
3124: if (node != null) {
3125: IALNodeDescription nodeDesc = (IALNodeDescription) node
3126: .getNodeDescription();
3127: // Setting the new next struct node ID and fragment node id since we have all the pushed fragments attached to the layout
3128: String newId = getNextStructId(person, "");
3129: nodeDesc.setId(newId);
3130: nodeDesc
3131: .setFragmentNodeId(strFragmentRootId);
3132: nodeDesc.setImmutable(true); // Pushed fragments are immutable
3133: nodeDesc.setUnremovable(true); // Pushed fragments are not removable
3134: // Remove the old node and put the new one with another ID
3135: layoutData.remove(key);
3136: layoutData.put(newId, node);
3137: if (lastNode != null) {
3138: lastNode.setNextNodeId(newId);
3139: node
3140: .setPreviousNodeId(lastNode
3141: .getId());
3142: } else
3143: rootNode.setFirstChildNodeId(newId);
3144:
3145: if (node.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
3146: //Changing the parent Ids for all the children
3147: for (String nextIdStr = ((ALFolder) node)
3148: .getFirstChildNodeId(); nextIdStr != null;) {
3149: ALNode child = (ALNode) layoutData
3150: .get(nextIdStr);
3151: child.setParentNodeId(newId);
3152: nextIdStr = child.getNextNodeId();
3153: }
3154: }
3155:
3156: node
3157: .setParentNodeId(IALFolderDescription.ROOT_FOLDER_ID);
3158: lastNode = node;
3159: }
3160: } // end for
3161: } // end if
3162:
3163: // Fixup the parentId of each channel in a folder inside a fragment
3164: for (Enumeration fragmentNodesEnum = fragmentNodes
3165: .keys(); fragmentNodesEnum.hasMoreElements();) {
3166: Object key = fragmentNodesEnum.nextElement();
3167: ALNode node = (ALNode) fragmentNodes.get(key);
3168: if (node.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
3169: String parentId = node.getId();
3170: // loop through all the channels in the folder and set the parentId
3171: for (String nextIdStr = ((ALFolder) node)
3172: .getFirstChildNodeId(); nextIdStr != null;) {
3173: ALNode child = (ALNode) layoutData
3174: .get(nextIdStr);
3175: child.setParentNodeId(parentId);
3176: nextIdStr = child.getNextNodeId();
3177: }
3178: }
3179: }
3180:
3181: if (log.isDebugEnabled()) {
3182: long stopTime = System.currentTimeMillis();
3183: log
3184: .debug("AggregatedUserLayoutStore::getUserLayout(): "
3185: + "Layout document for user "
3186: + userId
3187: + " took "
3188: + (stopTime - startTime)
3189: + " milliseconds to create");
3190: }
3191:
3192: } finally {
3193: if (insertStmt != null)
3194: insertStmt.close();
3195: if (stmt != null)
3196: stmt.close();
3197: }
3198:
3199: RDBMServices.commit(con);
3200: } catch (Exception e) {
3201: log.error("Error getting aggregated layout for user "
3202: + person, e);
3203: try {
3204: RDBMServices.rollback(con);
3205: } catch (SQLException sqle) {
3206: log.error(sqle.toString());
3207: }
3208: throw new PortalException(e);
3209: } finally {
3210: RDBMServices.releaseConnection(con);
3211: }
3212:
3213: layout.setLayoutData(layoutData);
3214: return layout;
3215: }
3216:
3217: /**
3218: * Returns the layout fragment as a user layout
3219: * @param person an <code>IPerson</code> object specifying the user
3220: * @param fragmentId a fragment ID
3221: * @return a <code>IAggregatedLayout</code> object containing the internal representation of the user layout
3222: * @exception PortalException if an error occurs
3223: */
3224: public ILayoutFragment getFragment(IPerson person, String fragmentId)
3225: throws PortalException {
3226: int userId = person.getID();
3227: Connection con = RDBMServices.getConnection();
3228: boolean permitted = false;
3229: try {
3230: String query = "SELECT OWNER_ID FROM UP_OWNER_FRAGMENT WHERE FRAGMENT_ID="
3231: + fragmentId + " AND OWNER_ID=" + userId;
3232: Statement stmt = con.createStatement();
3233: ResultSet rs = stmt.executeQuery(query);
3234: if (rs.next())
3235: permitted = true;
3236: rs.close();
3237:
3238: if (!permitted) {
3239: EntityIdentifier personIdentifier = person
3240: .getEntityIdentifier();
3241: IGroupMember groupPerson = GroupService
3242: .getGroupMember(personIdentifier);
3243: query = "SELECT GROUP_KEY FROM UP_GROUP_FRAGMENT WHERE FRAGMENT_ID="
3244: + fragmentId;
3245: rs = stmt.executeQuery(query);
3246: while (rs.next()) {
3247: IEntityGroup group = GroupService.findGroup(rs
3248: .getString(1));
3249: if (group != null
3250: && groupPerson.isDeepMemberOf(group)) {
3251: permitted = true;
3252: break;
3253: }
3254: }
3255: rs.close();
3256: }
3257: if (stmt != null)
3258: stmt.close();
3259: } catch (Exception e) {
3260: throw new PortalException(e);
3261: } finally {
3262: RDBMServices.releaseConnection(con);
3263: }
3264:
3265: if (permitted)
3266: return getFragment(fragmentId);
3267:
3268: throw new PortalException("The user with ID=" + userId
3269: + " is not allowed to get the fragment with ID="
3270: + fragmentId);
3271:
3272: }
3273:
3274: /**
3275: * Returns the layout fragment as a user layout
3276: * @param fragmentIdStr a fragment ID
3277: * @return a <code>IAggregatedLayout</code> object containing the internal representation of the user layout
3278: * @exception PortalException if an error occurs
3279: */
3280: protected ILayoutFragment getFragment(String fragmentIdStr)
3281: throws PortalException {
3282: int fragmentId = CommonUtils.parseInt(fragmentIdStr);
3283: ResultSet rs;
3284:
3285: ALFragment layout = new ALFragment(fragmentIdStr);
3286:
3287: Connection con = null;
3288: Hashtable layoutData = null;
3289: ALFolder rootNode = new ALFolder();
3290:
3291: try {
3292:
3293: con = RDBMServices.getConnection();
3294: //RDBMServices.setAutoCommit(con,false);
3295:
3296: Statement stmt = con.createStatement();
3297:
3298: layoutData = new Hashtable();
3299:
3300: long startTime = System.currentTimeMillis();
3301: // eventually, we need to fix template layout implementations so you can just do this:
3302: // int layoutId=profile.getLayoutId();
3303: // but for now:
3304:
3305: String restrFragmentSQL = "SELECT RESTRICTION_NAME, RESTRICTION_VALUE, RESTRICTION_TREE_PATH FROM UP_FRAGMENT_RESTRICTIONS "
3306: + "WHERE FRAGMENT_ID=? AND NODE_ID=?";
3307:
3308: int firstStructId = -1;
3309: String sQuery = "SELECT FRAGMENT_ROOT_ID,FRAGMENT_NAME,FRAGMENT_DESCRIPTION,PUSHED_FRAGMENT FROM UP_OWNER_FRAGMENT WHERE FRAGMENT_ID="
3310: + fragmentId;
3311: rs = stmt.executeQuery(sQuery);
3312: try {
3313: if (rs.next()) {
3314: firstStructId = rs.getInt(1);
3315: layout.setName(rs.getString(2));
3316: layout.setDescription(CommonUtils.nvl(rs
3317: .getString(3)));
3318: if ("Y".equals(rs.getString(4)))
3319: layout.setPushedFragment();
3320: else
3321: layout.setPulledFragment();
3322: }
3323: } finally {
3324: rs.close();
3325: }
3326:
3327: // Creating a root folder
3328: rootNode = ALFolder.createRootFolder();
3329:
3330: // Putting the root node
3331: layoutData.put(IALFolderDescription.ROOT_FOLDER_ID,
3332: rootNode);
3333: // Putting the lost folder
3334: layoutData.put(IALFolderDescription.LOST_FOLDER_ID,
3335: ALFolder.createLostFolder());
3336:
3337: // Setting the first layout node ID to the root folder
3338: if (firstStructId > 0)
3339: rootNode.setFirstChildNodeId(firstStructId + "");
3340: else
3341: rootNode.setFirstChildNodeId(null);
3342:
3343: // The query for getting information of the fragments
3344: String sqlFragment = "SELECT DISTINCT UF.NODE_ID,UF.NEXT_NODE_ID,UF.CHLD_NODE_ID,UF.PREV_NODE_ID,UF.PRNT_NODE_ID,UF.CHAN_ID,UF.NAME,UF.TYPE,UF.HIDDEN,"
3345: + "UF.UNREMOVABLE,UF.IMMUTABLE,UF.PRIORITY,UF.FRAGMENT_ID";
3346: sqlFragment += " FROM UP_FRAGMENTS UF, UP_OWNER_FRAGMENT UOF WHERE ";
3347: sqlFragment += " UF.FRAGMENT_ID=UOF.FRAGMENT_ID AND UOF.FRAGMENT_ID=?";
3348: log.debug("AggregatedUserLayoutStore::getFragment(): "
3349: + sqlFragment + " " + fragmentId);
3350: PreparedStatement psFragment = con
3351: .prepareStatement(sqlFragment);
3352: psFragment.setInt(1, fragmentId);
3353:
3354: List chanIds = Collections
3355: .synchronizedList(new ArrayList());
3356: StringBuffer structParms = new StringBuffer();
3357:
3358: rs = psFragment.executeQuery();
3359:
3360: try {
3361:
3362: int lastStructId = 0;
3363: String sepChar = "";
3364: if (rs.next()) {
3365: int structId = rs.getInt(1);
3366: readLayout: while (true) {
3367:
3368: int nextId = rs.getInt(2);
3369: int childId = rs.getInt(3);
3370: int prevId = rs.getInt(4);
3371: int prntId = rs.getInt(5);
3372: int chanId = rs.getInt(6);
3373:
3374: IALNodeDescription nodeDesc = null;
3375: // Trying to get the node if it already exists
3376: ALNode node;
3377: if (chanId <= 0) {
3378: node = new ALFolder();
3379: IALFolderDescription folderDesc = new ALFolderDescription();
3380: // If children exist in the folder
3381: ((ALFolder) node)
3382: .setFirstChildNodeId(childId > 0 ? childId
3383: + ""
3384: : null);
3385: String type = rs.getString(8);
3386: int intType;
3387: if ("header".equalsIgnoreCase(type))
3388: intType = UserLayoutFolderDescription.HEADER_TYPE;
3389: else if ("footer".equalsIgnoreCase(type))
3390: intType = UserLayoutFolderDescription.FOOTER_TYPE;
3391: else
3392: intType = UserLayoutFolderDescription.REGULAR_TYPE;
3393:
3394: folderDesc.setFolderType(intType);
3395: nodeDesc = folderDesc;
3396: } else {
3397: node = new ALChannel();
3398: ALChannelDescription channelDesc = new ALChannelDescription();
3399: channelDesc
3400: .setChannelPublishId(chanId + "");
3401: nodeDesc = channelDesc;
3402: }
3403:
3404: // Setting node description attributes
3405: if (node.getNodeType() == IUserLayoutNodeDescription.FOLDER)
3406: nodeDesc.setName(rs.getString(7));
3407: nodeDesc.setHidden(false);
3408: nodeDesc.setImmutable(false);
3409: nodeDesc.setUnremovable(false);
3410: node.setPriority(rs.getInt(12));
3411:
3412: nodeDesc.setFragmentId(fragmentIdStr);
3413:
3414: // Setting the node id
3415: nodeDesc.setId(structId + "");
3416:
3417: // Setting fragment parameters
3418: Map nodeAttributes = this .nodeAttributeService
3419: .attributesForFragmentNode(fragmentId,
3420: structId);
3421: node.putAttributes(nodeAttributes);
3422:
3423: // Setting the next node id
3424: if (nextId != 0) {
3425: node.setNextNodeId(nextId + "");
3426: }
3427:
3428: String parentId;
3429: switch (prntId) {
3430: case 0:
3431: parentId = IALFolderDescription.ROOT_FOLDER_ID;
3432: break;
3433: case LOST_FOLDER_ID:
3434: parentId = IALFolderDescription.LOST_FOLDER_ID;
3435: break;
3436: default:
3437: parentId = prntId + "";
3438:
3439: }
3440:
3441: // Setting up the parent id
3442: node.setParentNodeId(parentId);
3443:
3444: // Setting the previous node id
3445: if (prevId != 0) {
3446: node.setPreviousNodeId(prevId + "");
3447: }
3448:
3449: lastStructId = structId;
3450:
3451: // Putting the node into the layout hashtable with an appropriate key
3452: node.setNodeDescription(nodeDesc);
3453: layoutData.put(nodeDesc.getId(), node);
3454:
3455: // If there is a channel we need to get its parameters
3456: IALChannelDescription channelDesc = null;
3457: if (node.getNodeType() == IUserLayoutNodeDescription.CHANNEL) {
3458: channelDesc = (IALChannelDescription) nodeDesc;
3459: chanIds.add(nodeDesc.getId());
3460: }
3461:
3462: // getting restrictions for the nodes
3463: PreparedStatement psRestr = null;
3464: psRestr = con
3465: .prepareStatement(restrFragmentSQL);
3466: psRestr.setInt(1, fragmentId);
3467: psRestr.setInt(2, structId);
3468:
3469: ResultSet rsRestr = psRestr.executeQuery();
3470: while (rsRestr.next()) {
3471: String restrName = rsRestr.getString(1);
3472: String restrExp = rsRestr.getString(2);
3473: String restrPath = rsRestr.getString(3);
3474: if (restrPath == null
3475: || restrPath.trim().length() == 0)
3476: restrPath = IUserLayoutRestriction.LOCAL_RESTRICTION_PATH;
3477: IUserLayoutRestriction restriction = UserLayoutRestrictionFactory
3478: .createRestriction(restrName,
3479: restrExp, restrPath);
3480: nodeDesc.addRestriction(restriction);
3481: }
3482: rsRestr.close();
3483: if (psRestr != null)
3484: psRestr.close();
3485:
3486: // Adding the channel ID to the String buffer
3487: if (node.getNodeType() == IUserLayoutNodeDescription.CHANNEL) {
3488: structParms.append(sepChar + chanId);
3489: sepChar = ",";
3490: }
3491:
3492: if (rs.next()) {
3493: structId = rs.getInt(1);
3494: if (rs.wasNull()) {
3495: structId = 0;
3496: }
3497: } else {
3498: break readLayout;
3499: }
3500:
3501: // Setting up the priority values based on the appropriate priority restrictions
3502: PriorityRestriction priorityRestriction = AggregatedLayoutManager
3503: .getPriorityRestriction(node);
3504: if (priorityRestriction != null) {
3505: int priority = node.getPriority();
3506: int[] range = priorityRestriction
3507: .getRange();
3508:
3509: int newPriority = priority;
3510: if (range[0] > priority)
3511: newPriority = range[0];
3512: else if (range[1] < priority)
3513: newPriority = range[1];
3514:
3515: // Changing the node priority if it's been changed
3516: if (newPriority != priority)
3517: node.setPriority(newPriority);
3518: }
3519: } // while
3520: }
3521: } finally {
3522: rs.close();
3523: }
3524:
3525: // We have to retrieve the channel defition after the layout structure
3526: // since retrieving the channel data from the DB may interfere with the
3527: // layout structure ResultSet (in other words, Oracle is a pain to program for)
3528: if (chanIds.size() > 0) {
3529:
3530: for (int i = 0; i < chanIds.size(); i++) {
3531: String key = (String) chanIds.get(i);
3532: ALNode node = (ALNode) layoutData.get(key);
3533: fillChannelDescription((IALChannelDescription) node
3534: .getNodeDescription());
3535: } // end for
3536:
3537: chanIds.clear();
3538: }
3539:
3540: if (structParms.length() > 0) { // Pick up structure parameters
3541: String sql = "SELECT NODE_ID, PARAM_NAME, PARAM_VALUE FROM UP_FRAGMENT_PARAM WHERE FRAGMENT_ID="
3542: + fragmentId
3543: + " AND NODE_ID IN ("
3544: + structParms.toString() + ") ORDER BY NODE_ID";
3545: if (log.isDebugEnabled())
3546: log
3547: .debug("AggregatedUserLayoutStore::getFragment(): "
3548: + sql);
3549:
3550: // Adding this to prevent the error "closed statement" in Oracle
3551: Statement st = con.createStatement();
3552:
3553: rs = st.executeQuery(sql);
3554: try {
3555: if (rs.next()) {
3556: int structId = rs.getInt(1);
3557: readParm: while (true) {
3558: //LayoutStructure ls = (LayoutStructure)layoutStructure.get(new Integer(structId));
3559: ALNode node = (ALNode) layoutData
3560: .get(structId + "");
3561: if (node != null
3562: && node.getNodeType() == IUserLayoutNodeDescription.CHANNEL) {
3563: IALChannelDescription channelDesc = (IALChannelDescription) node
3564: .getNodeDescription();
3565: int lastStructId = structId;
3566: do {
3567: String name = rs.getString(2);
3568: String value = rs.getString(3);
3569: channelDesc.setParameterValue(name,
3570: value);
3571: if (!rs.next()) {
3572: break readParm;
3573: }
3574: } while ((structId = rs.getInt(1)) == lastStructId);
3575: } else
3576: break readParm; // if else
3577: }
3578: }
3579: } finally {
3580: rs.close();
3581: st.close();
3582: }
3583: }
3584:
3585: if (psFragment != null)
3586: psFragment.close();
3587: if (stmt != null)
3588: stmt.close();
3589:
3590: if (log.isDebugEnabled()) {
3591: long stopTime = System.currentTimeMillis();
3592: log
3593: .debug("AggregatedUserLayoutStore::getFragment(): The fragment took "
3594: + (stopTime - startTime)
3595: + " milliseconds to create");
3596: }
3597:
3598: } catch (Exception e) {
3599: log.error("Error concerning fragement " + fragmentIdStr, e);
3600: throw new PortalException(e);
3601: } finally {
3602: RDBMServices.releaseConnection(con);
3603: }
3604:
3605: layout.setLayoutData(layoutData);
3606: return layout;
3607: }
3608:
3609: public void fillChannelDescription(IALChannelDescription channelDesc)
3610: throws PortalException {
3611: try {
3612:
3613: String publishId = channelDesc.getChannelPublishId();
3614:
3615: if (publishId != null) {
3616:
3617: ChannelDefinition channelDef = crs
3618: .getChannelDefinition(CommonUtils
3619: .parseInt(publishId));
3620:
3621: if (channelDef == null
3622: || !channelApproved(channelDef
3623: .getApprovalDate())) {
3624: // Create an error channel if channel is missing or not approved
3625: ChannelDefinition cd = new ChannelDefinition(
3626: Integer.parseInt(publishId));
3627: cd.setTitle("Missing channel");
3628: cd.setName("Missing channel");
3629: cd.setTimeout(20000);
3630: cd.setJavaClass(CError.class.getName());
3631: cd.setEditable(false);
3632: cd.setHasAbout(false);
3633: cd.setHasHelp(false);
3634: String missingChannel = "Unknown";
3635: if (channelDef != null) {
3636: missingChannel = channelDef.getName();
3637: }
3638:
3639: String errMsg = "The '"
3640: + missingChannel
3641: + "' channel is no longer available. Please remove it from your layout.";
3642: cd.addParameter("CErrorChanId", publishId, String
3643: .valueOf(false));
3644: cd.addParameter("CErrorMessage", errMsg, String
3645: .valueOf(false));
3646: cd.addParameter("CErrorErrorId",
3647: ErrorCode.CHANNEL_MISSING_EXCEPTION
3648: .getCode()
3649: + "", String.valueOf(false));
3650: channelDef = cd;
3651: }
3652:
3653: channelDesc.setChannelTypeId(channelDef.getTypeId()
3654: + "");
3655: channelDesc.setClassName(channelDef.getJavaClass());
3656: channelDesc.setDescription(channelDef.getDescription());
3657: channelDesc.setEditable(channelDef.isEditable());
3658: channelDesc.setFunctionalName(CommonUtils
3659: .nvl(channelDef.getFName()));
3660: channelDesc.setHasAbout(channelDef.hasAbout());
3661: channelDesc.setHasHelp(channelDef.hasHelp());
3662: channelDesc.setIsSecure(channelDef.isSecure());
3663: channelDesc.setName(channelDef.getName());
3664: channelDesc.setTitle(channelDef.getTitle());
3665: channelDesc
3666: .setChannelPublishId(channelDef.getId() + "");
3667: ChannelParameter[] channelParams = channelDef
3668: .getParameters();
3669:
3670: for (int j = 0; j < channelParams.length; j++) {
3671: String paramName = channelParams[j].getName();
3672: String paramValue = channelParams[j].getValue();
3673: if (paramName != null
3674: && paramValue != null
3675: && channelDesc.getParameterValue(paramName) == null) {
3676: channelDesc.setParameterOverride(paramName,
3677: channelParams[j].getOverride());
3678: channelDesc.setParameterValue(paramName,
3679: paramValue);
3680: }
3681: }
3682: channelDesc.setTimeout(channelDef.getTimeout());
3683: channelDesc.setTitle(channelDef.getTitle());
3684:
3685: }
3686: } catch (Exception e) {
3687: throw new PortalException(e);
3688: }
3689:
3690: }
3691:
3692: /**
3693: * Returns the next fragment ID.
3694: *
3695: * @return a <code>String</code> next fragment ID
3696: * @exception PortalException if an error occurs
3697: */
3698: public String getNextFragmentId() throws PortalException {
3699:
3700: synchronized (fragmentLock) {
3701:
3702: int attemptsNumber = 20;
3703: Statement stmt = null;
3704: try {
3705: Connection con = RDBMServices.getConnection();
3706: try {
3707: RDBMServices.setAutoCommit(con, false);
3708: stmt = con.createStatement();
3709: String sQuery = "SELECT SEQUENCE_VALUE FROM UP_SEQUENCE WHERE SEQUENCE_NAME='UP_FRAGMENT'";
3710: for (int i = 0; i < attemptsNumber; i++) {
3711: try {
3712: if (log.isDebugEnabled())
3713: log
3714: .debug("AggregatedUserLayoutStore::getNextFragmentId(): "
3715: + sQuery);
3716: ResultSet rs = stmt.executeQuery(sQuery);
3717: int currentId = 0;
3718: rs.next();
3719: currentId = rs.getInt(1);
3720: if (rs != null)
3721: rs.close();
3722: String sUpdate = "UPDATE UP_SEQUENCE SET SEQUENCE_VALUE="
3723: + (currentId + 1)
3724: + " WHERE SEQUENCE_NAME='UP_FRAGMENT'";
3725: if (log.isDebugEnabled())
3726: log
3727: .debug("AggregatedUserLayoutStore::getNextFragmentId(): "
3728: + sUpdate);
3729: stmt.executeUpdate(sUpdate);
3730: RDBMServices.commit(con);
3731: return new String((currentId + 1) + "");
3732: } catch (Exception sqle) {
3733: RDBMServices.rollback(con);
3734: // Assume a concurrent update. Try again after some random amount of milliseconds.
3735: Thread.sleep(500); // Retry in up to 1/2 seconds
3736: }
3737: }
3738: } finally {
3739: if (stmt != null)
3740: stmt.close();
3741: RDBMServices.releaseConnection(con);
3742: }
3743: } catch (Exception e) {
3744: throw new PortalException(e);
3745: }
3746: throw new PortalException(
3747: "Unable to generate a new next fragment node id!");
3748: }
3749: }
3750:
3751: public ThemeStylesheetUserPreferences getThemeStylesheetUserPreferences(
3752: IPerson person, int profileId, int stylesheetId)
3753: throws Exception {
3754: int userId = person.getID();
3755: ThemeStylesheetUserPreferences tsup;
3756: Connection con = RDBMServices.getConnection();
3757: try {
3758: Statement stmt = con.createStatement();
3759: try {
3760: // get stylesheet description
3761: ThemeStylesheetDescription tsd = getThemeStylesheetDescription(stylesheetId);
3762:
3763: int layoutId = this .getLayoutID(userId, profileId);
3764: ResultSet rs;
3765:
3766: if (layoutId == 0) { // First time, grab the default layout for this user
3767: String sQuery = "SELECT USER_DFLT_USR_ID FROM UP_USER WHERE USER_ID="
3768: + userId;
3769: if (log.isDebugEnabled())
3770: log
3771: .debug("RDBMUserLayoutStore::getThemeStylesheetUserPreferences(): "
3772: + sQuery);
3773: rs = stmt.executeQuery(sQuery);
3774: try {
3775: rs.next();
3776: userId = rs.getInt(1);
3777: } finally {
3778: rs.close();
3779: }
3780: }
3781:
3782: // get user defined defaults
3783: String sQuery = "SELECT PARAM_NAME, PARAM_VAL FROM UP_SS_USER_PARM WHERE USER_ID="
3784: + userId
3785: + " AND PROFILE_ID="
3786: + profileId
3787: + " AND SS_ID="
3788: + stylesheetId
3789: + " AND SS_TYPE=2";
3790: if (log.isDebugEnabled())
3791: log
3792: .debug("RDBMUserLayoutStore::getThemeStylesheetUserPreferences(): "
3793: + sQuery);
3794: rs = stmt.executeQuery(sQuery);
3795: try {
3796: while (rs.next()) {
3797: // stylesheet param
3798: tsd.setStylesheetParameterDefaultValue(rs
3799: .getString(1), rs.getString(2));
3800: }
3801: } finally {
3802: rs.close();
3803: }
3804: tsup = new ThemeStylesheetUserPreferences();
3805: tsup.setStylesheetId(stylesheetId);
3806: // fill stylesheet description with defaults
3807: for (Enumeration e = tsd.getStylesheetParameterNames(); e
3808: .hasMoreElements();) {
3809: String pName = (String) e.nextElement();
3810: tsup.putParameterValue(pName, tsd
3811: .getStylesheetParameterDefaultValue(pName));
3812: }
3813: for (Enumeration e = tsd.getChannelAttributeNames(); e
3814: .hasMoreElements();) {
3815: String pName = (String) e.nextElement();
3816: tsup.addChannelAttribute(pName, tsd
3817: .getChannelAttributeDefaultValue(pName));
3818: }
3819: // get user preferences
3820: sQuery = "SELECT PARAM_TYPE, PARAM_NAME, PARAM_VAL, ULS.NODE_ID, CHAN_ID FROM UP_SS_USER_ATTS UUSA, UP_LAYOUT_STRUCT_AGGR ULS WHERE UUSA.USER_ID="
3821: + userId
3822: + " AND PROFILE_ID="
3823: + profileId
3824: + " AND SS_ID="
3825: + stylesheetId
3826: + " AND SS_TYPE=2 AND UUSA.STRUCT_ID = ULS.NODE_ID AND UUSA.USER_ID = ULS.USER_ID";
3827: if (log.isDebugEnabled())
3828: log
3829: .debug("RDBMUserLayoutStore::getThemeStylesheetUserPreferences(): "
3830: + sQuery);
3831: rs = stmt.executeQuery(sQuery);
3832: try {
3833: while (rs.next()) {
3834: int param_type = rs.getInt(1);
3835: if (rs.wasNull()) {
3836: param_type = 0;
3837: }
3838: int structId = rs.getInt(4);
3839: if (rs.wasNull()) {
3840: structId = 0;
3841: }
3842: int chanId = rs.getInt(5);
3843: if (rs.wasNull()) {
3844: chanId = 0;
3845: }
3846: if (param_type == 1) {
3847: // stylesheet param
3848: log
3849: .error("AggregatedUserLayoutStore::getThemeStylesheetUserPreferences() : stylesheet global params should be specified in the user defaults table ! UP_SS_USER_ATTS is corrupt. (userId="
3850: + Integer.toString(userId)
3851: + ", profileId="
3852: + Integer
3853: .toString(profileId)
3854: + ", stylesheetId="
3855: + Integer
3856: .toString(stylesheetId)
3857: + ", param_name=\""
3858: + rs.getString(2)
3859: + "\", param_type="
3860: + Integer
3861: .toString(param_type));
3862: } else if (param_type == 2) {
3863: // folder attribute
3864: log
3865: .error("AggregatedUserLayoutStore::getThemeStylesheetUserPreferences() : folder attribute specified for the theme stylesheet! UP_SS_USER_ATTS corrupt. (userId="
3866: + Integer.toString(userId)
3867: + ", profileId="
3868: + Integer
3869: .toString(profileId)
3870: + ", stylesheetId="
3871: + Integer
3872: .toString(stylesheetId)
3873: + ", param_name=\""
3874: + rs.getString(2)
3875: + "\", param_type="
3876: + Integer
3877: .toString(param_type));
3878: } else if (param_type == 3) {
3879: // channel attribute
3880: tsup.setChannelAttributeValue(getStructId(
3881: structId, chanId), rs.getString(2),
3882: rs.getString(3));
3883: } else {
3884: // unknown param type
3885: log
3886: .error("AggregatedUserLayoutStore::getThemeStylesheetUserPreferences() : unknown param type encountered! DB corrupt. (userId="
3887: + Integer.toString(userId)
3888: + ", profileId="
3889: + Integer
3890: .toString(profileId)
3891: + ", stylesheetId="
3892: + Integer
3893: .toString(stylesheetId)
3894: + ", param_name=\""
3895: + rs.getString(2)
3896: + "\", param_type="
3897: + Integer
3898: .toString(param_type));
3899: }
3900: }
3901: } finally {
3902: rs.close();
3903: }
3904: } finally {
3905: stmt.close();
3906: }
3907: } finally {
3908: RDBMServices.releaseConnection(con);
3909: }
3910: return tsup;
3911: }
3912:
3913: public StructureStylesheetUserPreferences getStructureStylesheetUserPreferences(
3914: IPerson person, int profileId, int stylesheetId)
3915: throws Exception {
3916: int userId = person.getID();
3917: StructureStylesheetUserPreferences ssup;
3918: Connection con = RDBMServices.getConnection();
3919: try {
3920: Statement stmt = con.createStatement();
3921: try {
3922: // get stylesheet description
3923: StructureStylesheetDescription ssd = getStructureStylesheetDescription(stylesheetId);
3924: // get user defined defaults
3925: String subSelectString = "SELECT LAYOUT_ID FROM UP_USER_PROFILE WHERE USER_ID="
3926: + userId + " AND PROFILE_ID=" + profileId;
3927: if (log.isDebugEnabled())
3928: log
3929: .debug("RDBMUserLayoutStore::getStructureStylesheetUserPreferences(): "
3930: + subSelectString);
3931: int layoutId = 0;
3932: ResultSet rs = stmt.executeQuery(subSelectString);
3933: try {
3934: if (rs.next()) {
3935: layoutId = rs.getInt(1);
3936: }
3937: } finally {
3938: rs.close();
3939: }
3940:
3941: if (layoutId == 0) { // First time, grab the default layout for this user
3942: String sQuery = "SELECT USER_DFLT_USR_ID FROM UP_USER WHERE USER_ID="
3943: + userId;
3944: if (log.isDebugEnabled())
3945: log
3946: .debug("RDBMUserLayoutStore::getStructureStylesheetUserPreferences(): "
3947: + sQuery);
3948: rs = stmt.executeQuery(sQuery);
3949: try {
3950: rs.next();
3951: userId = rs.getInt(1);
3952: } finally {
3953: rs.close();
3954: }
3955: }
3956:
3957: String sQuery = "SELECT PARAM_NAME, PARAM_VAL FROM UP_SS_USER_PARM WHERE USER_ID="
3958: + userId
3959: + " AND PROFILE_ID="
3960: + profileId
3961: + " AND SS_ID="
3962: + stylesheetId
3963: + " AND SS_TYPE=1";
3964: if (log.isDebugEnabled())
3965: log
3966: .debug("RDBMUserLayoutStore::getStructureStylesheetUserPreferences(): "
3967: + sQuery);
3968: rs = stmt.executeQuery(sQuery);
3969: try {
3970: while (rs.next()) {
3971: // stylesheet param
3972: ssd.setStylesheetParameterDefaultValue(rs
3973: .getString(1), rs.getString(2));
3974: }
3975: } finally {
3976: rs.close();
3977: }
3978: ssup = new StructureStylesheetUserPreferences();
3979: ssup.setStylesheetId(stylesheetId);
3980: // fill stylesheet description with defaults
3981: for (Enumeration e = ssd.getStylesheetParameterNames(); e
3982: .hasMoreElements();) {
3983: String pName = (String) e.nextElement();
3984: ssup.putParameterValue(pName, ssd
3985: .getStylesheetParameterDefaultValue(pName));
3986: }
3987: for (Enumeration e = ssd.getChannelAttributeNames(); e
3988: .hasMoreElements();) {
3989: String pName = (String) e.nextElement();
3990: ssup.addChannelAttribute(pName, ssd
3991: .getChannelAttributeDefaultValue(pName));
3992: }
3993: for (Enumeration e = ssd.getFolderAttributeNames(); e
3994: .hasMoreElements();) {
3995: String pName = (String) e.nextElement();
3996: ssup.addFolderAttribute(pName, ssd
3997: .getFolderAttributeDefaultValue(pName));
3998: }
3999: // get user preferences
4000: sQuery = "SELECT PARAM_NAME, PARAM_VAL, PARAM_TYPE, ULS.NODE_ID, CHAN_ID FROM UP_SS_USER_ATTS UUSA, UP_LAYOUT_STRUCT_AGGR ULS WHERE UUSA.USER_ID="
4001: + userId
4002: + " AND PROFILE_ID="
4003: + profileId
4004: + " AND SS_ID="
4005: + stylesheetId
4006: + " AND SS_TYPE=1 AND UUSA.STRUCT_ID = ULS.NODE_ID AND UUSA.USER_ID = ULS.USER_ID";
4007: if (log.isDebugEnabled())
4008: log
4009: .debug("RDBMUserLayoutStore::getStructureStylesheetUserPreferences(): "
4010: + sQuery);
4011: rs = stmt.executeQuery(sQuery);
4012: try {
4013: while (rs.next()) {
4014: String temp1 = rs.getString(1); // Access columns left to right
4015: String temp2 = rs.getString(2);
4016: int param_type = rs.getInt(3);
4017: int structId = rs.getInt(4);
4018: if (rs.wasNull()) {
4019: structId = 0;
4020: }
4021: int chanId = rs.getInt(5);
4022: if (rs.wasNull()) {
4023: chanId = 0;
4024: }
4025:
4026: if (param_type == 1) {
4027: // stylesheet param
4028: log
4029: .error("AggregatedUserLayoutStore::getStructureStylesheetUserPreferences() : stylesheet global params should be specified in the user defaults table ! UP_SS_USER_ATTS is corrupt. (userId="
4030: + Integer.toString(userId)
4031: + ", profileId="
4032: + Integer
4033: .toString(profileId)
4034: + ", stylesheetId="
4035: + Integer
4036: .toString(stylesheetId)
4037: + ", param_name=\""
4038: + temp1
4039: + "\", param_type="
4040: + Integer
4041: .toString(param_type));
4042: } else if (param_type == 2) {
4043: // folder attribute
4044: ssup.setFolderAttributeValue(getStructId(
4045: structId, chanId), temp1, temp2);
4046: } else if (param_type == 3) {
4047: // channel attribute
4048: ssup.setChannelAttributeValue(getStructId(
4049: structId, chanId), temp1, temp2);
4050: } else {
4051: // unknown param type
4052: log
4053: .error("AggregatedUserLayoutStore::getStructureStylesheetUserPreferences() : unknown param type encountered! DB corrupt. (userId="
4054: + Integer.toString(userId)
4055: + ", profileId="
4056: + Integer
4057: .toString(profileId)
4058: + ", stylesheetId="
4059: + Integer
4060: .toString(stylesheetId)
4061: + ", param_name=\""
4062: + temp1
4063: + "\", param_type="
4064: + Integer
4065: .toString(param_type));
4066: }
4067: }
4068: } finally {
4069: rs.close();
4070: }
4071: } finally {
4072: stmt.close();
4073: }
4074: } finally {
4075: RDBMServices.releaseConnection(con);
4076: }
4077: return ssup;
4078: }
4079:
4080: /**
4081: * Returns the list of pushed fragment node IDs that must be removed from the user layout.
4082: * @param person an <code>IPerson</code> object specifying the user
4083: * @param profile a user profile for which the layout is being stored
4084: * @return a <code>Set</code> list containing the fragment node IDs to be deleted from the user layout
4085: * @exception PortalException if an error occurs
4086: */
4087: public Set getIncorrectPushedFragmentNodes(IPerson person,
4088: UserProfile profile) throws PortalException {
4089: int userId = person.getID();
4090: int layoutId = profile.getLayoutId();
4091: Set incorrectIds = new HashSet();
4092: Set correctIds = new HashSet();
4093: Connection con = RDBMServices.getConnection();
4094: try {
4095: IGroupMember groupPerson = null;
4096: String query1 = "SELECT ULS.FRAGMENT_ID,ULS.NODE_ID,UGF.GROUP_KEY FROM UP_LAYOUT_STRUCT_AGGR ULS,UP_OWNER_FRAGMENT UOF,UP_GROUP_FRAGMENT UGF WHERE "
4097: + "UOF.PUSHED_FRAGMENT='Y' AND ULS.USER_ID="
4098: + userId
4099: + " AND ULS.LAYOUT_ID="
4100: + layoutId
4101: + " AND ULS.FRAGMENT_ID=UOF.FRAGMENT_ID AND ULS.FRAGMENT_ID=UGF.FRAGMENT_ID";
4102: Statement stmt = con.createStatement();
4103: ResultSet rs = stmt.executeQuery(query1);
4104: Set groupKeys = new HashSet();
4105:
4106: while (rs.next()) {
4107: if (groupPerson == null) {
4108: EntityIdentifier personIdentifier = person
4109: .getEntityIdentifier();
4110: groupPerson = GroupService
4111: .getGroupMember(personIdentifier);
4112: }
4113: String nodeId = rs.getInt(2) + "";
4114: String groupKey = rs.getString(3);
4115: if (!correctIds.contains(nodeId)) {
4116: boolean isGroupKey = groupKeys.contains(groupKey);
4117: if (!isGroupKey) {
4118: IEntityGroup group = GroupService
4119: .findGroup(groupKey);
4120: if (group == null
4121: || !groupPerson.isDeepMemberOf(group)) {
4122: if (!incorrectIds.contains(nodeId))
4123: incorrectIds.add(nodeId);
4124: groupKeys.add(groupKey);
4125: } else {
4126: correctIds.add(nodeId);
4127: incorrectIds.remove(nodeId);
4128: }
4129: } else if (isGroupKey
4130: && !incorrectIds.contains(nodeId))
4131: incorrectIds.add(nodeId);
4132: }
4133: }
4134: if (rs != null)
4135: rs.close();
4136: if (stmt != null)
4137: stmt.close();
4138: } catch (Exception e) {
4139: throw new PortalException(e);
4140: } finally {
4141: RDBMServices.releaseConnection(con);
4142: }
4143: return incorrectIds;
4144: }
4145:
4146: /**
4147: * Returns the list of Ids of the fragments that the user can subscribe to
4148: * @param person an <code>IPerson</code> object specifying the user
4149: * @return <code>Collection</code> a set of the fragment IDs
4150: * @exception PortalException if an error occurs
4151: */
4152: public Collection getSubscribableFragments(IPerson person)
4153: throws PortalException {
4154: Set fragmentIds = new HashSet();
4155: Connection con = RDBMServices.getConnection();
4156: try {
4157: IGroupMember groupPerson = null;
4158: String query1 = "SELECT UGF.FRAGMENT_ID,UGF.GROUP_KEY FROM UP_GROUP_FRAGMENT UGF, UP_OWNER_FRAGMENT UOF WHERE UOF.FRAGMENT_ID=UGF.FRAGMENT_ID"
4159: + " AND UOF.PUSHED_FRAGMENT='N'";
4160: Statement stmt = con.createStatement();
4161: ResultSet rs = stmt.executeQuery(query1);
4162: Set groupKeys = new HashSet();
4163:
4164: while (rs.next()) {
4165: if (groupPerson == null) {
4166: EntityIdentifier personIdentifier = person
4167: .getEntityIdentifier();
4168: groupPerson = GroupService
4169: .getGroupMember(personIdentifier);
4170: }
4171: int fragmentId = rs.getInt(1);
4172: String groupKey = rs.getString(2);
4173: String fragStrId = Integer.toString(fragmentId);
4174: if (!fragmentIds.contains(fragStrId)) {
4175: if (groupKeys.contains(groupKey))
4176: fragmentIds.add(fragStrId);
4177: else {
4178: IEntityGroup group = GroupService
4179: .findGroup(groupKey);
4180: if (group != null
4181: && groupPerson.isDeepMemberOf(group)) {
4182: fragmentIds.add(fragStrId);
4183: groupKeys.add(groupKey);
4184: }
4185: }
4186: }
4187: }
4188: if (rs != null)
4189: rs.close();
4190: if (stmt != null)
4191: stmt.close();
4192: } catch (Exception e) {
4193: throw new PortalException(e);
4194: } finally {
4195: RDBMServices.releaseConnection(con);
4196: }
4197: return fragmentIds;
4198: }
4199:
4200: /**
4201: * Returns the user group keys which the fragment is published to
4202: * @param person an <code>IPerson</code> object specifying the user
4203: * @param fragmentId a <code>String</code> value
4204: * @return a <code>Collection</code> object containing the group keys
4205: * @exception PortalException if an error occurs
4206: */
4207: public Collection getPublishGroups(IPerson person, String fragmentId)
4208: throws PortalException {
4209: int userId = person.getID();
4210: Vector groupKeys = new Vector();
4211: Connection con = RDBMServices.getConnection();
4212: try {
4213: String query1 = "SELECT UGF.GROUP_KEY FROM UP_GROUP_FRAGMENT UGF, UP_OWNER_FRAGMENT UOF WHERE UOF.FRAGMENT_ID=UGF.FRAGMENT_ID"
4214: + " AND UGF.FRAGMENT_ID="
4215: + fragmentId
4216: + " AND UOF.OWNER_ID=" + userId;
4217: Statement stmt = con.createStatement();
4218: ResultSet rs = stmt.executeQuery(query1);
4219:
4220: while (rs.next()) {
4221: String groupKey = rs.getString(1);
4222: if (groupKey != null)
4223: groupKeys.add(groupKey);
4224: }
4225: if (rs != null)
4226: rs.close();
4227: if (stmt != null)
4228: stmt.close();
4229: } catch (Exception e) {
4230: throw new PortalException(e);
4231: } finally {
4232: RDBMServices.releaseConnection(con);
4233: }
4234: return groupKeys;
4235: }
4236:
4237: /**
4238: * Persists the user groups which the fragment is published to
4239: * @param groups an array of <code>IGroupMember</code> objects
4240: * @param person an <code>IPerson</code> object specifying the user
4241: * @param fragmentId a <code>String</code> value
4242: * @exception PortalException if an error occurs
4243: */
4244: public void setPublishGroups(IGroupMember[] groups, IPerson person,
4245: String fragmentId) throws PortalException {
4246: int userId = person.getID();
4247: Connection con = RDBMServices.getConnection();
4248: try {
4249:
4250: boolean isUpdateAllowed = false;
4251: String query = "SELECT OWNER_ID FROM UP_OWNER_FRAGMENT WHERE FRAGMENT_ID="
4252: + fragmentId + " AND OWNER_ID=" + userId;
4253: Statement stmt = con.createStatement();
4254: ResultSet rs = stmt.executeQuery(query);
4255: if (rs.next())
4256: isUpdateAllowed = true;
4257: rs.close();
4258:
4259: if (isUpdateAllowed) {
4260: RDBMServices.setAutoCommit(con, false);
4261: // Deleting all the group key for the given fragment
4262: stmt
4263: .executeUpdate("DELETE FROM UP_GROUP_FRAGMENT WHERE FRAGMENT_ID="
4264: + fragmentId);
4265: PreparedStatement ps = con
4266: .prepareStatement("INSERT INTO UP_GROUP_FRAGMENT (GROUP_KEY,FRAGMENT_ID) VALUES (?,"
4267: + fragmentId + ")");
4268: for (int i = 0; i < groups.length; i++) {
4269: ps.setString(1, groups[i].getKey());
4270: ps.executeUpdate();
4271: }
4272: ps.close();
4273: RDBMServices.commit(con);
4274: }
4275: if (stmt != null)
4276: stmt.close();
4277: } catch (Exception e) {
4278: throw new PortalException(e);
4279: } finally {
4280: RDBMServices.releaseConnection(con);
4281: }
4282: }
4283:
4284: /**
4285: * Returns the priority range defined for the given user group
4286: * @param groupKey a <code>String</code> group key
4287: * @return a int array containing the min and max priority values
4288: * @exception PortalException if an error occurs
4289: */
4290: public int[] getPriorityRange(String groupKey)
4291: throws PortalException {
4292: Connection con = RDBMServices.getConnection();
4293: try {
4294: int[] range = new int[2];
4295: String query = "SELECT MIN_PRIORITY, MAX_PRIORITY FROM UP_GROUP_PRIORITY_RANGE WHERE GROUP_KEY='"
4296: + groupKey + "'";
4297: Statement stmt = con.createStatement();
4298: ResultSet rs = stmt.executeQuery(query);
4299: if (rs.next()) {
4300: range[0] = rs.getInt(1);
4301: range[1] = rs.getInt(2);
4302: }
4303: rs.close();
4304: if (stmt != null)
4305: stmt.close();
4306: return (range[1] > 0) ? range : new int[] {};
4307: } catch (Exception e) {
4308: throw new PortalException(e);
4309: } finally {
4310: RDBMServices.releaseConnection(con);
4311: }
4312: }
4313:
4314: public String getNextNodeId(IPerson person) throws PortalException {
4315: try {
4316: return getNextStructId(person, "");
4317: } catch (Exception e) {
4318: throw new PortalException(e);
4319: }
4320: }
4321:
4322: /**
4323: * Compares the current aggregated layout with the specified one
4324: * and performs and smart-update of the aggregated layout stored
4325: * in the database.
4326: */
4327: private void updateUserLayoutNodes(IPerson person,
4328: UserProfile profile, IAggregatedLayout newLayout,
4329: Connection con) throws PortalException {
4330:
4331: int userId = person.getID();
4332: int profileId = profile.getProfileId();
4333: int newLayoutId = Integer.parseInt(newLayout.getId());
4334:
4335: ResultSet rs = null;
4336: PreparedStatement detectLayout = null;
4337: PreparedStatement psDeleteLayoutRestriction = null;
4338:
4339: AggregatedLayout currentLayout = null;
4340: Set currentNodeSet = null;
4341: Enumeration currentNodeIds = null;
4342:
4343: // Indicates whether a layout already exists for the user or not
4344: boolean layoutExists = false;
4345:
4346: try {
4347:
4348: // Determine whether a layout already exists for this user
4349: detectLayout = con
4350: .prepareStatement("SELECT USER_ID FROM UP_USER_LAYOUT_AGGR WHERE USER_ID=? AND LAYOUT_ID=?");
4351:
4352: detectLayout.setInt(1, userId);
4353: detectLayout.setInt(2, newLayoutId);
4354:
4355: rs = detectLayout.executeQuery();
4356:
4357: if (rs.next()) {
4358: layoutExists = true;
4359: }
4360:
4361: rs.close();
4362: rs = null;
4363:
4364: // Delete node restrictions and retrieve current layout
4365: // only if the user had a layout persisted already
4366: if (layoutExists) {
4367:
4368: // Retrieve existing user layout
4369: currentLayout = (AggregatedLayout) getAggregatedLayout(
4370: person, profile);
4371: currentNodeIds = currentLayout.getNodeIds();
4372: currentNodeSet = new HashSet();
4373:
4374: // Store all current node ids in a set
4375: while (currentNodeIds.hasMoreElements()) {
4376: String id = (String) currentNodeIds.nextElement();
4377: currentNodeSet.add(id);
4378: }
4379: }
4380:
4381: // Set of new nodes in the new layout
4382: Set newNodeSet = new HashSet();
4383:
4384: // Add new nodes and update existing ones
4385: for (Enumeration nodeIds = newLayout.getNodeIds(); nodeIds
4386: .hasMoreElements();) {
4387:
4388: String strNodeId = nodeIds.nextElement().toString();
4389:
4390: newNodeSet.add(strNodeId);
4391:
4392: if (!strNodeId
4393: .equals(IALFolderDescription.ROOT_FOLDER_ID)
4394: && !strNodeId
4395: .equals(IALFolderDescription.LOST_FOLDER_ID)) {
4396:
4397: ALNode node = ((AggregatedLayout) newLayout)
4398: .getNode(strNodeId);
4399: int nodeId = CommonUtils.parseInt(node.getId());
4400:
4401: int fragmentId = CommonUtils.parseInt(node
4402: .getFragmentId());
4403: int fragmentNodeId = CommonUtils.parseInt(node
4404: .getFragmentNodeId());
4405:
4406: if (fragmentId > 0 && fragmentNodeId <= 0)
4407: continue;
4408:
4409: // Determine whether the node is new or an existing one
4410: // In the case where a layout does not exist yet, all nodes are new ones
4411: if (layoutExists
4412: && currentNodeSet.contains(strNodeId)) {
4413: // Perform an update
4414: updateUserLayoutNode(person, profile, node, con);
4415: } else {
4416: // Perform an add
4417: addUserLayoutNode(person, profile, node, con);
4418: }
4419: }
4420: }
4421:
4422: if (layoutExists) {
4423:
4424: currentNodeIds = currentLayout.getNodeIds();
4425: String currentNodeId = null;
4426:
4427: // Remove all nodes that exist in the current layout but not in the
4428: // new layout
4429: while (currentNodeIds.hasMoreElements()) {
4430:
4431: currentNodeId = (String) currentNodeIds
4432: .nextElement();
4433:
4434: if (!newNodeSet.contains(currentNodeId)) {
4435: // Deleting a node that was removed from the layout
4436: ALNode deletedNode = ((AggregatedLayout) currentLayout)
4437: .getNode(currentNodeId);
4438: deleteUserLayoutNode(person, profile,
4439: deletedNode, con);
4440: }
4441: }
4442: }
4443: } catch (Exception e) {
4444: e.printStackTrace();
4445: String errorMessage = e.getMessage();
4446: try {
4447: RDBMServices.rollback(con);
4448: } catch (SQLException sqle) {
4449: log.error(sqle.toString());
4450: errorMessage += ":" + sqle.getMessage();
4451: }
4452: throw new PortalException(errorMessage, e);
4453: } finally {
4454: try {
4455: // Ensure resouces are closed/cleaned-up
4456: if (rs != null) {
4457: rs.close();
4458: }
4459: if (detectLayout != null) {
4460: detectLayout.close();
4461: }
4462: } catch (Exception e) {
4463: log
4464: .error("AggregatedUserLayoutStore::setAggregatedLayout(): Failed to clean up resources.");
4465: }
4466: }
4467: }
4468:
4469: private void syncUserAttributes(Connection con, int realUserId,
4470: int templateUserId) throws SQLException {
4471: PreparedStatement ps = null;
4472: ResultSet rs = null;
4473: Set realUserAttributesSet = new HashSet();
4474: Map realUserAttributesMap = new HashMap();
4475: Set templateUserAttributesSet = new HashSet();
4476: int userId;
4477: UserAttributes userAttributes;
4478: UserAttributes realUserAttributes;
4479: Set insertRows = new HashSet();
4480: Set updateRows = new HashSet();
4481: Set deleteRows = new HashSet();
4482:
4483: try {
4484: final String getUserAttrsSql = "SELECT USER_ID, PROFILE_ID, SS_ID, SS_TYPE, STRUCT_ID, PARAM_NAME, PARAM_TYPE, PARAM_VAL "
4485: + " FROM UP_SS_USER_ATTS WHERE USER_ID IN (?,?)";
4486:
4487: ps = con.prepareStatement(getUserAttrsSql);
4488:
4489: int i = 1;
4490: ps.setInt(i++, realUserId);
4491: ps.setInt(i++, templateUserId);
4492:
4493: rs = ps.executeQuery();
4494:
4495: while (rs.next()) {
4496: userId = rs.getInt("USER_ID");
4497: userAttributes = new UserAttributes(rs
4498: .getInt("PROFILE_ID"), rs.getInt("SS_ID"), rs
4499: .getInt("SS_TYPE"), rs.getInt("STRUCT_ID"), rs
4500: .getString("PARAM_NAME"), rs
4501: .getInt("PARAM_TYPE"), rs
4502: .getString("PARAM_VAL"));
4503:
4504: if (userId == realUserId) {
4505: realUserAttributesSet.add(userAttributes);
4506: // need to maintain a map for the real user's attributes
4507: // for updates.
4508: realUserAttributesMap.put(new Integer(
4509: userAttributes.hashCode()), userAttributes);
4510: } else {
4511: templateUserAttributesSet.add(userAttributes);
4512: }
4513: }
4514:
4515: // use set operations to determine update, insert, delete buckets
4516:
4517: deleteRows.addAll(realUserAttributesSet);
4518: deleteRows.removeAll(templateUserAttributesSet);
4519:
4520: insertRows.addAll(templateUserAttributesSet);
4521: insertRows.removeAll(realUserAttributesSet);
4522:
4523: // this will destroy the realUserAttributesSet, so it's the last one we do
4524: Iterator itr = templateUserAttributesSet.iterator();
4525: while (itr.hasNext()) {
4526: userAttributes = (UserAttributes) itr.next();
4527: realUserAttributes = (UserAttributes) realUserAttributesMap
4528: .get(new Integer(userAttributes.hashCode()));
4529: if (realUserAttributes != null
4530: && !userAttributes.getParamValue().equals(
4531: realUserAttributes.getParamValue())) {
4532: updateRows.add(userAttributes);
4533: }
4534: }
4535: } finally {
4536: RDBMServices.closeResultSet(rs);
4537: RDBMServices.closePreparedStatement(ps);
4538: }
4539:
4540: insertUserAttributes(con, insertRows, realUserId);
4541: deleteUserAttributes(con, deleteRows, realUserId);
4542: updateUserAttributes(con, updateRows, realUserId);
4543: }
4544:
4545: private void insertUserAttributes(Connection con, Set insertRows,
4546: int userId) throws SQLException {
4547: PreparedStatement ps = null;
4548: UserAttributes userAttributes;
4549: final String sql = "INSERT INTO UP_SS_USER_ATTS "
4550: + "(USER_ID, PROFILE_ID, SS_ID, SS_TYPE, STRUCT_ID, PARAM_NAME, PARAM_TYPE, PARAM_VAL) "
4551: + "VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
4552:
4553: try {
4554: ps = con.prepareStatement(sql);
4555:
4556: Iterator itr = insertRows.iterator();
4557: while (itr.hasNext()) {
4558: userAttributes = (UserAttributes) itr.next();
4559:
4560: int i = 1;
4561: ps.setInt(i++, userId);
4562: ps.setInt(i++, userAttributes.getProfileId());
4563: ps.setInt(i++, userAttributes.getSsId());
4564: ps.setInt(i++, userAttributes.getSsType());
4565: ps.setInt(i++, userAttributes.getStructId());
4566: ps.setString(i++, userAttributes.getParamName());
4567: ps.setInt(i++, userAttributes.getParamType());
4568: ps.setString(i++, userAttributes.getParamValue());
4569:
4570: ps.executeUpdate();
4571: }
4572: } finally {
4573: RDBMServices.closePreparedStatement(ps);
4574: }
4575: }
4576:
4577: private void deleteUserAttributes(Connection con, Set deleteRows,
4578: int userId) throws SQLException {
4579: PreparedStatement ps = null;
4580: UserAttributes userAttributes;
4581: final String sql = "DELETE FROM UP_SS_USER_ATTS WHERE USER_ID = ? AND "
4582: + "PROFILE_ID = ? AND SS_ID = ? AND SS_TYPE = ? AND STRUCT_ID = ? AND "
4583: + "PARAM_NAME = ? AND PARAM_TYPE = ?";
4584:
4585: try {
4586: ps = con.prepareStatement(sql);
4587:
4588: Iterator itr = deleteRows.iterator();
4589: while (itr.hasNext()) {
4590: userAttributes = (UserAttributes) itr.next();
4591:
4592: int i = 1;
4593: ps.setInt(i++, userId);
4594: ps.setInt(i++, userAttributes.getProfileId());
4595: ps.setInt(i++, userAttributes.getSsId());
4596: ps.setInt(i++, userAttributes.getSsType());
4597: ps.setInt(i++, userAttributes.getStructId());
4598: ps.setString(i++, userAttributes.getParamName());
4599: ps.setInt(i++, userAttributes.getParamType());
4600:
4601: ps.executeUpdate();
4602: }
4603: } finally {
4604: RDBMServices.closePreparedStatement(ps);
4605: }
4606: }
4607:
4608: private void updateUserAttributes(Connection con, Set updateRows,
4609: int userId) throws SQLException {
4610: PreparedStatement ps = null;
4611: UserAttributes userAttributes;
4612: final String sql = "UPDATE UP_SS_USER_ATTS SET PARAM_VAL = ? WHERE USER_ID = ? AND "
4613: + "PROFILE_ID = ? AND SS_ID = ? AND SS_TYPE = ? AND STRUCT_ID = ? AND "
4614: + "PARAM_NAME = ? AND PARAM_TYPE = ?";
4615:
4616: try {
4617: ps = con.prepareStatement(sql);
4618:
4619: Iterator itr = updateRows.iterator();
4620: while (itr.hasNext()) {
4621: userAttributes = (UserAttributes) itr.next();
4622:
4623: int i = 1;
4624: ps.setString(i++, userAttributes.getParamValue());
4625: ps.setInt(i++, userId);
4626: ps.setInt(i++, userAttributes.getProfileId());
4627: ps.setInt(i++, userAttributes.getSsId());
4628: ps.setInt(i++, userAttributes.getSsType());
4629: ps.setInt(i++, userAttributes.getStructId());
4630: ps.setString(i++, userAttributes.getParamName());
4631: ps.setInt(i++, userAttributes.getParamType());
4632:
4633: ps.executeUpdate();
4634: }
4635: } finally {
4636: RDBMServices.closePreparedStatement(ps);
4637: }
4638: }
4639:
4640: /**
4641: * A class that handles the theme/structure stylesheet attributes. Objects
4642: * are considered *equal* if their keys, which is all the attributes besides value,
4643: * match.
4644: */
4645: public class UserAttributes {
4646: private int profileId;
4647: private int ssId;
4648: private int ssType;
4649: private int structId;
4650: private String paramName;
4651: private int paramType;
4652: private String paramValue;
4653: private String str;
4654:
4655: public UserAttributes(int profileId, int ssId, int ssType,
4656: int structId, String paramName, int paramType,
4657: String paramValue) {
4658: this .profileId = profileId;
4659: this .ssId = ssId;
4660: this .ssType = ssType;
4661: this .structId = structId;
4662: this .paramName = paramName;
4663: this .paramType = paramType;
4664: this .paramValue = paramValue;
4665:
4666: this .str = new StringBuffer().append(profileId).append('.')
4667: .append(ssId).append('.').append(ssType)
4668: .append('.').append(structId).append('.').append(
4669: paramName).append('.').append(paramType)
4670: .toString();
4671: }
4672:
4673: public String toString() {
4674: return str;
4675: }
4676:
4677: public boolean equals(Object obj) {
4678: if (obj == null || !(obj instanceof UserAttributes))
4679: return false;
4680: return this .hashCode() == ((UserAttributes) obj).hashCode();
4681: }
4682:
4683: public int hashCode() {
4684: return str.hashCode();
4685: }
4686:
4687: public int getProfileId() {
4688: return profileId;
4689: }
4690:
4691: public int getSsId() {
4692: return ssId;
4693: }
4694:
4695: public int getSsType() {
4696: return ssType;
4697: }
4698:
4699: public int getStructId() {
4700: return structId;
4701: }
4702:
4703: public String getParamName() {
4704: return paramName;
4705: }
4706:
4707: public int getParamType() {
4708: return paramType;
4709: }
4710:
4711: public String getParamValue() {
4712: return paramValue;
4713: }
4714: }
4715: }
|