/* Copyright 2005 The JA-SIG Collaborative. All rights reserved. * See license distributed with this file and * available online at http://www.uportal.org/license.html */ package org.jasig.portal.layout.dlm; import java.io.PrintWriter; import java.io.StringWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Properties; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jasig.portal.ChannelDefinition; import org.jasig.portal.properties.PropertiesManager; import org.jasig.portal.RDBMServices; import org.jasig.portal.layout.simple.RDBMUserLayoutStore; import org.jasig.portal.ChannelParameter; import org.jasig.portal.PortalException; import org.jasig.portal.PortalSessionManager; import org.jasig.portal.StructureStylesheetDescription; import org.jasig.portal.StructureStylesheetUserPreferences; import org.jasig.portal.ThemeStylesheetDescription; import org.jasig.portal.ThemeStylesheetUserPreferences; import org.jasig.portal.UserProfile; import org.jasig.portal.channels.error.ErrorCode; import org.jasig.portal.layout.LayoutStructure; import org.jasig.portal.layout.StructureParameter; import org.jasig.portal.rdbm.DatabaseMetaDataImpl; import org.jasig.portal.rdbm.IDatabaseMetadata; import org.jasig.portal.security.IPerson; import org.jasig.portal.security.provider.PersonImpl; import org.jasig.portal.utils.DocumentFactory; import org.jasig.portal.utils.SmartCache; import org.jasig.portal.utils.XML; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap; import edu.emory.mathcs.backport.java.util.concurrent.locks.ReadWriteLock; import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantReadWriteLock; /** * This class extends RDBMUserLayoutStore and implements instantiating and * storing layouts that conform to the design of the distribute layout * management system. These layouts consist of two types: layout fragments * that are the layouts owned by a user specified in dlm.xml, and composite * view layouts which represent regular users with zero or more UI elements * incorporated from layout fragments. Only a user's personal layout fragment * is * * @version $Revision: 36782 $ $Date: 2007-08-21 21:56:30 -0700 (Tue, 21 Aug 2007) $ * @since uPortal 2.5 */ public class RDBMDistributedLayoutStore extends RDBMUserLayoutStore { public static final String RCS_ID = "@(#) $Header$"; private static final Log LOG = LogFactory.getLog(RDBMDistributedLayoutStore.class); private String systemDefaultUser = null; private boolean systemDefaultUserLoaded = false; private Properties properties = null; private FragmentDefinition[] definitions = null; private Map fragmentInfoCache = null; private LayoutDecorator decorator = null; private FragmentActivator activator = null; private Object initializationLock = new Object(); private boolean initialized = false; static final String TEMPLATE_USER_NAME = "org.jasig.portal.services.Authentication.defaultTemplateUserName"; static final String DECORATOR_PROPERTY = "layoutDecorator"; private static final int THEME = 0; private static final int STRUCT = 1; // Cache for theme stylesheet descriptors private static SmartCache tsdCache; // Cache for structure stylesheet descriptors private static SmartCache ssdCache; /** Map of read/writer lock objects; one per unique person. */ private Map mLocks = new ConcurrentHashMap(); /** * Method for acquiring copies of fragment layouts to assist in debugging. * No infrastructure code calls this but channels designed to expose the * structure of the cached fragments use this to obtain copies. * @return Map */ public Map getFragmentLayoutCopies() throws Exception { if ( ! initialized ) { synchronized( initializationLock ) { if ( ! initialized ) { initializationLock.wait(); } } } Map layouts = new HashMap(); for(int i=0; definitions != null && i definitions.length-1 ) return 0; // must pass through the array looking for the fragment with this // index since the array was sorted by precedence and then index // within precedence. for ( int i=0; i " : " " ) + folder + "." + attrib + " = (" + defVal + ") "+ ( val != null ? val : "" ) ); } } pw.close(); return sw.toString(); } private String showChannelAttribs( ThemeStylesheetUserPreferences tsup ) { StringWriter sw = new StringWriter (); PrintWriter pw = new PrintWriter( sw ); pw.println( "\n*** Channel Attributes" ); for ( Enumeration channels = tsup.getChannels(); channels.hasMoreElements(); ) { String channel = (String) channels.nextElement(); for ( Enumeration attribs = tsup.getChannelAttributeNames(); attribs.hasMoreElements(); ) { String attrib = (String) attribs.nextElement(); String val = tsup.getChannelAttributeValue( channel, attrib ); String defVal = tsup.getDefinedChannelAttributeValue( channel, attrib ); pw.println( ( val != null ? "> " : " " ) + channel + "." + attrib + " = (" + defVal + ") "+ ( val != null ? val : "" ) ); } } pw.close(); return sw.toString(); } /** If the passed in user represents a layout owner then replace the cached structure stylesheet user preferences with the passed in one after modifying it for incorporation. */ private void updateFragmentSSUP( IPerson person, DistributedUserPreferences ssup ) { FragmentDefinition ownedFragment = getOwnedFragment( person ); if ( ownedFragment == null ) return; // make a copy so the original is unchanged for the user try { UserProfile profile = getUserProfileById(person, 1); ssup = new DistributedUserPreferences( (StructureStylesheetUserPreferences) ssup); UserView view = new UserView(profile, ownedFragment.view.layout, ssup, ownedFragment.view.themeUserPrefs); activator.fragmentizeSSUP(view, ownedFragment); ownedFragment.view = view; } catch( Exception e) { LOG.error(" *** Error - DLM unable to update fragment prefs: \n\n", e ); } } /** When user preferences are stored in the database for changes made to an incorporated node the node id can not be used because it does not represent a row in the up_layout_struct table for the user. The plfid must be used. Null will never be returned unless the layout or processing has really been screwed up. This is because changes made to the user prefs calls UserPrefsHandler which generates a shadow node in the db and sets the plfid of that node into the corresponding node in the PLF prior to the call to update the user prefs in the db. */ private String getPlfId( Document PLF, String incdId ) { Element element = PLF.getElementById( incdId ); if ( element == null ) return null; Attr attr = element.getAttributeNode( Constants.ATT_PLF_ID ); if ( attr == null ) return null; return attr.getValue(); } protected Element getStructure(Document doc, LayoutStructure ls) throws Exception { Element structure = null; // handle migration of legacy namespace String type = ls.getType(); if (type != null && type.startsWith(Constants.LEGACY_NS)) type = Constants.NS + type.substring(Constants.LEGACY_NS.length()); if (ls.isChannel()) { ChannelDefinition channelDef = crs.getChannelDefinition(ls.getChanId()); if (channelDef != null && channelApproved(channelDef.getApprovalDate())) { if (localeAware) { channelDef.setLocale(ls.getLocale()); // for i18n by Shoji } structure = channelDef.getDocument(doc, channelPrefix + ls.getStructId()); } else { // Create an error channel if channel is missing or not approved ChannelDefinition cd = new ChannelDefinition(ls.getChanId()); cd.setTitle("Missing channel"); cd.setName("Missing channel"); cd.setTimeout(20000); String missingChannel = "Unknown"; if (channelDef != null) { missingChannel = channelDef.getName(); } structure = cd.getDocument(doc, channelPrefix + ls.getStructId(), "The '" + missingChannel + "' channel is no longer available. " + "Please remove it from your layout.", ErrorCode.CHANNEL_MISSING_EXCEPTION.getCode()); } } else { // create folder objects including dlm new types in cp namespace if (type != null && (type.startsWith(Constants.NS))) { structure = doc.createElementNS(Constants.NS_URI, type); } else structure = doc.createElement("folder"); structure.setAttribute("name", ls.getName()); structure.setAttribute("type", (type != null ? type : "regular")); } structure.setAttribute("hidden", (ls.isHidden() ? "true" : "false")); structure.setAttribute("immutable", (ls.isImmutable() ? "true" : "false")); structure.setAttribute("unremovable", (ls.isUnremovable() ? "true" : "false")); if (localeAware) { structure.setAttribute("locale", ls.getLocale()); // for i18n by Shoji } /* * Parameters from up_layout_param are loaded slightly differently for * folders and channels. For folders all parameters are added as attributes * of the Element. For channels only those parameters with names starting * with the dlm namespace Constants.NS are added as attributes to the Element. * Others are added as child parameter Elements. */ if (ls.getParameters() != null) { for (Iterator itr = ls.getParameters().iterator(); itr.hasNext();) { StructureParameter sp = (StructureParameter) itr.next(); String pName = sp.getName(); // handle migration of legacy namespace if (pName.startsWith(Constants.LEGACY_NS)) pName = Constants.NS + sp.getName().substring(Constants.LEGACY_NS.length()); if (!ls.isChannel()) { // Folder if (pName.startsWith(Constants.NS)) structure.setAttributeNS(Constants.NS_URI, pName, sp.getValue()); else structure.setAttribute(pName, sp.getValue()); } else // Channel { // if dealing with a dlm namespace param add as attribute if (pName.startsWith(Constants.NS)) { structure.setAttributeNS(Constants.NS_URI, pName, sp.getValue()); itr.remove(); } else { /* * do traditional override processing. some explanation is in * order. The structure element was created by the * ChannelDefinition and only contains parameter children if the * definition had defined parameters. These are checked for each * layout loaded parameter as found in LayoutStructure.parameters. * If a name match is found then we need to see if overriding is * allowed and if so we set the value on the child parameter * element. At that point we are done with that version loaded * from the layout so we remove it from the in-memory set of * parameters that are being merged-in. Then, after all such have * been checked against those added by the channel definition we * add in any remaining as adhoc, unregulated parameters. */ NodeList nodeListParameters = structure.getElementsByTagName("parameter"); for (int j = 0; j < nodeListParameters.getLength(); j++) { Element parmElement = (Element)nodeListParameters.item(j); NamedNodeMap nm = parmElement.getAttributes(); String nodeName = nm.getNamedItem("name").getNodeValue(); if (nodeName.equals(pName)) { Node override = nm.getNamedItem("override"); if (override != null && override.getNodeValue().equals("yes")) { Node valueNode = nm.getNamedItem("value"); valueNode.setNodeValue(sp.getValue()); } itr.remove(); break; // found the corresponding one so skip the rest } } } } } // For channels, add any remaining parameter elements loaded with the // layout as adhoc, unregulated, parameter children that can be overridden. if (ls.isChannel()) { for (Iterator itr = ls.getParameters().iterator(); itr.hasNext();) { StructureParameter sp = (StructureParameter) itr.next(); Element parameter = doc.createElement("parameter"); parameter.setAttribute("name", sp.getName()); parameter.setAttribute("value", sp.getValue()); parameter.setAttribute("override", "yes"); structure.appendChild(parameter); } } } // finish setting up elements based on loaded params String origin = structure.getAttribute(Constants.ATT_ORIGIN); String prefix = (ls.isChannel() ? channelPrefix : folderPrefix); // if not null we are dealing with a node incorporated from another // layout and this node contains changes made by the user so handle // id swapping. if (!origin.equals("")) { structure.setAttributeNS( Constants.NS_URI, Constants.ATT_PLF_ID, prefix + ls.getStructId()); structure.setAttribute("ID", origin); } else if (!ls.isChannel()) // regular folder owned by this user, need to check if this is a // directive or ui element. If the latter then use traditional id // structure { if (type != null && type.startsWith(Constants.NS)) { structure.setAttribute( "ID", Constants.DIRECTIVE_PREFIX + ls.getStructId()); } else { structure.setAttribute("ID", folderPrefix + ls.getStructId()); } } else { if (LOG.isDebugEnabled()) LOG.debug("Adding identifier " + folderPrefix + ls.getStructId() ); structure.setAttribute("ID", channelPrefix + ls.getStructId()); } structure.setIdAttribute(Constants.ATT_ID, true); return structure; } protected int saveStructure( Node node, PreparedStatement structStmt, PreparedStatement parmStmt) throws Exception { if (node == null || node.getNodeName().equals("parameter")) { // No more or parameter node return 0; } Element structure = (Element) node; if (LOG.isDebugEnabled()) LOG.debug("saveStructure XML content: " + XML.serializeNode(node)); // determine the struct_id for storing in the db. For incorporated nodes in // the plf their ID is a system-wide unique ID while their struct_id for // storing in the db is cached in a dlm:plfID attribute. int saveStructId = -1; String plfID = structure.getAttribute(Constants.ATT_PLF_ID); if (!plfID.equals("")) saveStructId = Integer.parseInt(plfID.substring(1)); else saveStructId = Integer.parseInt(structure.getAttribute("ID").substring(1)); int nextStructId = 0; int childStructId = 0; int chanId = -1; boolean isChannel = node.getNodeName().equals("channel"); if (node.hasChildNodes()) { childStructId = saveStructure(node.getFirstChild(), structStmt, parmStmt); } nextStructId = saveStructure(node.getNextSibling(), structStmt, parmStmt); structStmt.clearParameters(); structStmt.setInt(1, saveStructId); structStmt.setInt(2, nextStructId); structStmt.setInt(3, childStructId); String externalId = structure.getAttribute("external_id"); if (externalId != null && externalId.trim().length() > 0) { Integer eID = new Integer(externalId); structStmt.setInt(4, eID.intValue()); } else { structStmt.setNull(4, java.sql.Types.NUMERIC); } if (isChannel) { chanId = Integer.parseInt( node.getAttributes().getNamedItem("chanID").getNodeValue()); structStmt.setInt(5, chanId); structStmt.setNull(6, java.sql.Types.VARCHAR); } else { structStmt.setNull(5, java.sql.Types.NUMERIC); structStmt.setString(6, structure.getAttribute("name")); } String structType = structure.getAttribute("type"); structStmt.setString(7, structType); structStmt.setString( 8, RDBMServices.dbFlag(xmlBool(structure.getAttribute("hidden")))); structStmt.setString( 9, RDBMServices.dbFlag(xmlBool(structure.getAttribute("immutable")))); structStmt.setString( 10, RDBMServices.dbFlag( xmlBool(structure.getAttribute("unremovable")))); if (LOG.isDebugEnabled()) LOG.debug(structStmt.toString()); structStmt.executeUpdate(); // code to persist extension attributes for dlm NamedNodeMap attribs = node.getAttributes(); for (int i = 0; i < attribs.getLength(); i++) { Node attrib = attribs.item(i); String name = attrib.getNodeName(); if (name.startsWith(Constants.NS) && !name.equals(Constants.ATT_PLF_ID) && !name.equals(Constants.ATT_FRAGMENT) && !name.equals(Constants.ATT_PRECEDENCE)) { // a cp extension attribute. Push into param table. parmStmt.clearParameters(); parmStmt.setInt(1, saveStructId); parmStmt.setString(2, name); parmStmt.setString(3, attrib.getNodeValue()); if (LOG.isDebugEnabled()) LOG.debug(parmStmt.toString()); parmStmt.executeUpdate(); } } NodeList parameters = node.getChildNodes(); if (parameters != null && isChannel) { ChannelDefinition channelDef = crs.getChannelDefinition(chanId); for (int i = 0; i < parameters.getLength(); i++) { if (parameters.item(i).getNodeName().equals("parameter")) { Element parmElement = (Element) parameters.item(i); NamedNodeMap nm = parmElement.getAttributes(); String parmName = nm.getNamedItem("name").getNodeValue(); String parmValue = nm.getNamedItem("value").getNodeValue(); Node override = nm.getNamedItem("override"); // if no override specified then default to allowed if (override != null && !override.getNodeValue().equals("yes")) { // can't override } else { // override only for adhoc or if diff from chan def ChannelParameter cp = channelDef.getParameter(parmName); if (cp == null || !cp.getValue().equals(parmValue)) { parmStmt.clearParameters(); parmStmt.setInt(1, saveStructId); parmStmt.setString(2, parmName); parmStmt.setString(3, parmValue); if (LOG.isDebugEnabled()) LOG.debug(parmStmt); parmStmt.executeUpdate(); } } } } } return saveStructId; } public static Document getPLF( IPerson person ) throws PortalException { try { return (Document) person.getAttribute( Constants.PLF ); } catch ( Exception ex ) { throw new PortalException( ex ); } } public void setStructureStylesheetUserPreferences( IPerson person, int profileId, StructureStylesheetUserPreferences ssup ) throws Exception { DistributedUserPreferences dssup = (DistributedUserPreferences) ssup; int userId = person.getID(); Document PLF = (Document) person.getAttribute( Constants.PLF ); if ( PLF == null ) throw new Exception( "Unable to obtain user's PLF to translate" + " incorporated ids to plfIds." ); int stylesheetId = ssup.getStylesheetId(); StructureStylesheetDescription ssDesc = getStructureStylesheetDescription(stylesheetId); Connection con = RDBMServices.getConnection(); try { // Set autocommit false for the connection RDBMServices.setAutoCommit(con, false); Statement stmt = con.createStatement(); PreparedStatement pstmt = null; try { // before writing out params clean out old values deleteFromUpSsUserParm(stmt, userId, profileId, stylesheetId,1); // write out params only if specified in stylesheet's .sdf file for (Enumeration e = ssup.getParameterValues().keys(); e.hasMoreElements();) { String pName = (String)e.nextElement(); if (ssDesc.containsParameterName(pName) && ! ssDesc.getStylesheetParameterDefaultValue(pName) .equals(ssup.getParameterValue(pName))) { String pNameEscaped = RDBMServices.sqlEscape(pName); String sQuery = "INSERT INTO UP_SS_USER_PARM (USER_ID,PROFILE_ID,SS_ID,SS_TYPE,PARAM_NAME,PARAM_VAL) VALUES (" + userId + "," + profileId + "," + stylesheetId + ",1,'" + pNameEscaped + "','" + ssup.getParameterValue(pName) + "')"; if (LOG.isDebugEnabled()) LOG.debug(sQuery); stmt.executeUpdate(sQuery); } } // now before writing out folders and channels clean out old values deleteFromUpSsUserAtts(stmt, userId, profileId, stylesheetId,1); // write out folder attributes pstmt = con.prepareStatement(INSERT__INTO__UP_SS_USER_ATTS); for (Enumeration e = ssup.getFolders(); e.hasMoreElements();) { String folderId = (String)e.nextElement(); String plfId = folderId; if ( folderId.startsWith( Constants.FRAGMENT_ID_USER_PREFIX ) ) // icorporated node plfId = getPlfId( PLF, folderId ); if ( plfId == null ) //couldn't translate, skip continue; for (Enumeration attre = ssup.getFolderAttributeNames(); attre.hasMoreElements();) { String pName = (String)attre.nextElement(); String pValue = ssup.getDefinedFolderAttributeValue(folderId, pName); /* * Persist folder attributes defined in the stylesheet * description only if the user value is non null and * there is no default or the user value * differs from the default. */ if (ssDesc.containsFolderAttribute(pName)) { String deflt = dssup .getDefaultFolderAttributeValue(folderId, pName); if(pValue != null && (deflt == null || ! pValue.equals(deflt))) insertIntoUpSsUserAtts(pstmt, userId, profileId, stylesheetId, 1, plfId, 2, pName, pValue); } } } // write out channel attributes for (Enumeration e = ssup.getChannels(); e.hasMoreElements();) { String channelId = (String)e.nextElement(); String plfId = channelId; if ( plfId.startsWith( Constants.FRAGMENT_ID_USER_PREFIX ) ) // icorporated node plfId = getPlfId( PLF, channelId ); if ( plfId == null ) //couldn't translate, skip continue; for (Enumeration attre = ssup.getChannelAttributeNames(); attre.hasMoreElements();) { String pName = (String)attre.nextElement(); String pValue = ssup.getDefinedChannelAttributeValue(channelId, pName); /* * Persist channel attributes defined in the stylesheet * description only if the user value is non null and * there is no default or the user value * differs from the default. */ if (ssDesc.containsChannelAttribute(pName)) { String deflt = dssup .getDefaultChannelAttributeValue(channelId, pName); if(pValue != null && (deflt == null || ! pValue.equals(deflt))) insertIntoUpSsUserAtts(pstmt, userId, profileId, stylesheetId, 1, plfId, 3, pName, pValue); } } } // Commit the transaction RDBMServices.commit(con); updateFragmentSSUP( person, (DistributedUserPreferences) ssup ); } catch (Exception e) { if (LOG.isDebugEnabled()) LOG.debug("Problem occurred ", e); // Roll back the transaction RDBMServices.rollback(con); throw new Exception("Exception setting Structure Sylesheet " + "User Preferences",e); } finally { stmt.close(); if (pstmt != null) pstmt.close(); } } finally { RDBMServices.releaseConnection(con); } } public void setThemeStylesheetUserPreferences (IPerson person, int profileId, ThemeStylesheetUserPreferences tsup) throws Exception { DistributedUserPreferences dtsup = (DistributedUserPreferences) tsup; int userId = person.getID(); Document PLF = (Document) person.getAttribute( Constants.PLF ); if ( PLF == null ) throw new Exception( "Unable to obtain user's PLF to translate" + " incorporated ids to plfIds." ); int stylesheetId = tsup.getStylesheetId(); ThemeStylesheetDescription tsDesc = getThemeStylesheetDescription(stylesheetId); Connection con = RDBMServices.getConnection(); try { // Set autocommit false for the connection RDBMServices.setAutoCommit(con, false); Statement stmt = con.createStatement(); PreparedStatement pstmt = null; try { // before writing out params clean out old values deleteFromUpSsUserParm(stmt, userId, profileId, stylesheetId,2); // write out params only if defined in stylesheet's .sdf file // and user's value differs from default for (Enumeration e = tsup.getParameterValues().keys(); e.hasMoreElements();) { String pName = (String)e.nextElement(); if (tsDesc.containsParameterName(pName) && ! tsDesc.getStylesheetParameterDefaultValue(pName) .equals(tsup.getParameterValue(pName))) { String pNameEscaped = RDBMServices.sqlEscape(pName); String sQuery = "INSERT INTO UP_SS_USER_PARM (USER_ID,PROFILE_ID,SS_ID,SS_TYPE,PARAM_NAME,PARAM_VAL) VALUES (" + userId + "," + profileId + "," + stylesheetId + ",2,'" + pNameEscaped + "','" + tsup.getParameterValue(pName) + "')"; if (LOG.isDebugEnabled()) LOG.debug(sQuery); stmt.executeUpdate(sQuery); } } // now before writing out channel atts clean out old values deleteFromUpSsUserAtts(stmt, userId, profileId, stylesheetId,2); // write out channel attributes pstmt = con.prepareStatement(INSERT__INTO__UP_SS_USER_ATTS); for (Enumeration e = tsup.getChannels(); e.hasMoreElements();) { String channelId = (String)e.nextElement(); String plfChannelId = channelId; if ( plfChannelId.startsWith( Constants.FRAGMENT_ID_USER_PREFIX ) ) // icorporated node plfChannelId = getPlfId( PLF, channelId ); if ( plfChannelId == null ) //couldn't translate, skip continue; for (Enumeration attre = tsup.getChannelAttributeNames(); attre.hasMoreElements();) { String pName = (String)attre.nextElement(); String pValue = tsup.getDefinedChannelAttributeValue(channelId, pName); /* * Persist channel attributes defined in the stylesheet * description only if the user value is non null and * there is no default or the user value * differs from the default. */ if (tsDesc.containsChannelAttribute(pName)) { String deflt = dtsup .getDefaultChannelAttributeValue(channelId, pName); if(pValue != null && (deflt == null || ! pValue.equals(deflt))) insertIntoUpSsUserAtts(pstmt, userId, profileId, stylesheetId, 2, plfChannelId, 3, pName, pValue); } } } // Commit the transaction RDBMServices.commit(con); // add a method nearly identical to updateFragmentSSUP() if // we want to push things like minimized state of a channel in // a fragment. (TBD: mboyd if needed) // updateFragmentTSUP(); } catch (Exception e) { // Roll back the transaction RDBMServices.rollback(con); throw new Exception("Exception setting Theme Sylesheet " + "User Preferences",e); } finally { stmt.close(); if (pstmt != null) pstmt.close(); } } finally { RDBMServices.releaseConnection(con); } } private static final String INSERT__INTO__UP_SS_USER_ATTS = "INSERT INTO UP_SS_USER_ATTS " + "(USER_ID," + "PROFILE_ID," + "SS_ID," + "SS_TYPE," + // 1=structure, 2=theme "STRUCT_ID," + "PARAM_TYPE," + // 2=folder, 3=channel, 1=sheet parm not allowed "PARAM_NAME," + "PARAM_VAL) " + "VALUES (?,?,?,?,?,?,?,?)"; /** * Handles inserts into the UP_SS_USER_ATTS table. * * @param pstmt * @param userId * @param profileId * @param stylesheetId * @param stylesheetType * @param nodeId * @param parmType * @param parmName * @param parmValue * @throws SQLException */ private void insertIntoUpSsUserAtts( PreparedStatement pstmt, int userId, int profileId, int stylesheetId, int stylesheetType, // 1=structure, 2=theme String nodeId, int parmType, // 2=folder, 1=channel String parmName, String parmValue ) throws SQLException { int structId = Integer.parseInt(nodeId.substring(1)); pstmt.setInt(1, userId); pstmt.setInt(2, profileId); pstmt.setInt(3, stylesheetId); pstmt.setInt(4, stylesheetType); pstmt.setInt(5, structId); pstmt.setInt(6, parmType); pstmt.setString(7, parmName); pstmt.setString(8, parmValue); if (LOG.isDebugEnabled()) { LOG.debug(INSERT__INTO__UP_SS_USER_ATTS + ": with values" + " USER_ID=" + userId + ", PROFILE_ID=" + profileId + ", SS_ID=" + stylesheetId + ", SS_TYPE=" + stylesheetType + ", STRUCT_ID=" + structId + ", PARAM_TYPE=" + parmType + ", PARAM_NAME=" + parmName + ", PARAM_VAL=" + parmValue); } pstmt.execute(); } /** * Handles deletes from UP_SS_USER_PARM table. * * @param stmt * @param userId * @param profileId * @param stylesheetId * @param stylesheetType * @throws SQLException */ private void deleteFromUpSsUserParm(Statement stmt, int userId, int profileId, int stylesheetId, int stylesheetType) throws SQLException { String sQuery = "DELETE FROM UP_SS_USER_PARM " + "WHERE USER_ID=" + userId + " AND " + "PROFILE_ID=" + profileId + " AND " + "SS_ID=" + stylesheetId + " AND SS_TYPE=" + stylesheetType; if (LOG.isDebugEnabled()) LOG.debug(sQuery); stmt.executeUpdate(sQuery); } /** * Handles deletes from UP_SS_USER_ATTS table. * * @param stmt * @param userId * @param profileId * @param stylesheetId * @param stylesheetType * @throws SQLException */ private void deleteFromUpSsUserAtts(Statement stmt, int userId, int profileId, int stylesheetId, int stylesheetType) throws SQLException { String sQuery = "DELETE FROM UP_SS_USER_ATTS " + "WHERE USER_ID=" + userId + " AND " + "PROFILE_ID=" + profileId + " AND " + "SS_ID=" + stylesheetId + " AND SS_TYPE=" + stylesheetType; if (LOG.isDebugEnabled()) { LOG.debug(sQuery); } stmt.executeUpdate(sQuery); } }