/* * Copyright 2000-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jetspeed.modules.actions.portlets; // Turbine stuff import org.apache.turbine.util.DynamicURI; import org.apache.turbine.util.RunData; import org.apache.turbine.util.StringUtils; import org.apache.turbine.util.security.EntityExistsException; import org.apache.turbine.services.TurbineServices; import org.apache.turbine.services.servlet.TurbineServlet; import org.apache.turbine.services.resources.ResourceService; // Velocity Stuff import org.apache.velocity.context.Context; //Java import java.io.File; import java.io.FileWriter; import java.io.FileReader; import java.io.IOException; import java.util.Iterator; import java.util.Vector; import java.util.StringTokenizer; //Jetspeed import org.apache.commons.lang.SerializationUtils; import org.apache.jetspeed.modules.actions.portlets.security.SecurityConstants; import org.apache.jetspeed.om.profile.Profile; import org.apache.jetspeed.om.profile.ProfileLocator; import org.apache.jetspeed.om.profile.QueryLocator; import org.apache.jetspeed.om.profile.PSMLDocument; import org.apache.jetspeed.om.profile.Portlets; import org.apache.jetspeed.portal.portlets.VelocityPortlet; import org.apache.jetspeed.services.Profiler; import org.apache.jetspeed.services.Registry; import org.apache.jetspeed.services.JetspeedSecurity; import org.apache.jetspeed.services.PsmlManager; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.jetspeed.util.template.JetspeedLink; import org.apache.jetspeed.util.template.JetspeedLinkFactory; import org.apache.jetspeed.services.resources.JetspeedResources; import org.apache.jetspeed.services.psmlmanager.PsmlManagerService; import org.apache.jetspeed.om.profile.BasePSMLDocument; import org.apache.jetspeed.om.security.JetspeedUser; import org.apache.jetspeed.om.security.Role; import org.apache.jetspeed.om.security.Group; //castor support import org.exolab.castor.xml.MarshalException; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.Unmarshaller; import org.exolab.castor.xml.ValidationException; import org.exolab.castor.mapping.Mapping; import org.exolab.castor.mapping.MappingException; import org.xml.sax.InputSource; // serialization support import org.apache.xml.serialize.Serializer; import org.apache.xml.serialize.XMLSerializer; import org.apache.xml.serialize.OutputFormat; /** * This action enables to update the psml entries * * @author <a href="mailto:david@apache.org">David Sean Taylor</a> * @version $Id: PsmlUpdateAction.java,v 1.18 2004/03/31 04:49:10 morciuch Exp $ */ public class PsmlUpdateAction extends SecureVelocityPortletAction { protected static final String PSML_REFRESH_FLAG = "psmlRefreshFlag"; protected static final String TRUE = "true"; protected static final String FALSE = "false"; protected static final String CATEGORY_NAME = "categoryName"; protected static final String CATEGORY_VALUE = "categoryValue"; protected static final String COPY_FROM = "copyFrom"; protected static final String COPY_TO = "copyTo"; protected static final String TEMP_LOCATOR = "tempLocator"; protected static final String PSML_UPDATE_PANE = "PsmlForm"; /** * Static initialization of the logger for this class */ private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(PsmlUpdateAction.class.getName()); /** * Subclasses must override this method to provide default behavior * for the portlet action */ /** * Build the normal state content for this portlet. * * @param portlet The velocity-based portlet that is being built. * @param context The velocity context for this request. * @param rundata The turbine rundata context for this request. */ protected void buildNormalContext( VelocityPortlet portlet, Context context, RunData rundata ) { try { // // if there was an error, display the message // String msgid = rundata.getParameters().getString(SecurityConstants.PARAM_MSGID); if (msgid != null) { int id = Integer.parseInt(msgid); if (id < SecurityConstants.MESSAGES.length) context.put(SecurityConstants.PARAM_MSG, SecurityConstants.MESSAGES[id]); // get the bad entered data and put it back for convenient update ProfileLocator locator = (ProfileLocator)rundata.getUser().getTemp(TEMP_LOCATOR); if (locator != null) context.put("profile", Profiler.createProfile(locator)); } String mode = rundata.getParameters().getString(SecurityConstants.PARAM_MODE); context.put(SecurityConstants.PARAM_MODE, mode); String path = rundata.getParameters().getString(SecurityConstants.PARAM_ENTITY_ID); if(mode != null && mode.equals(SecurityConstants.PARAM_MODE_DELETE)) { ProfileLocator locator = Profiler.createLocator(); locator.createFromPath(path); Profile profile = Profiler.getProfile(locator); if (profile != null) { rundata.getUser().setTemp(TEMP_LOCATOR, locator); context.put("profile", profile); } else logger.error("Profile for Path:"+path+" Not Found!"); } if(mode != null && mode.equals(SecurityConstants.PARAM_MODE_INSERT)) { org.apache.jetspeed.om.registry.Registry mediaTypes = Registry.get(Registry.MEDIA_TYPE); context.put("mediaTypes", mediaTypes.listEntryNames()); if (msgid == null) { if(path == null) { context.put(CATEGORY_NAME, "user"); context.put("categoryValue", "anon"); context.put("copyFrom", "user/anon/media-type/html/page/default.psml"); } else { ProfileLocator tmpLocator = Profiler.createLocator(); tmpLocator.createFromPath(path); Profile profile = Profiler.getProfile(tmpLocator); if (profile != null) { rundata.getUser().setTemp(TEMP_LOCATOR, tmpLocator); context.put("profile", profile); } String categoryName = "group"; String categoryValue = tmpLocator.getGroupName(); if (categoryValue == null) { categoryName = "role"; categoryValue = tmpLocator.getRoleName(); if (categoryValue == null) { categoryName = "user"; categoryValue = tmpLocator.getUserName(); if (categoryValue == null) { categoryName = "user"; categoryValue = "anon"; } } } context.put(CATEGORY_NAME, categoryName); context.put("categoryValue", categoryValue); context.put("copyFrom", path); } } else { context.put(CATEGORY_NAME, rundata.getUser().getTemp(CATEGORY_NAME)); context.put(CATEGORY_VALUE, rundata.getUser().getTemp(CATEGORY_VALUE)); context.put(COPY_FROM, rundata.getUser().getTemp(COPY_FROM)); } } if(mode != null && mode.equals("export")) { if (msgid == null) { String tmpPath = JetspeedResources.getString(JetspeedResources.TEMP_DIRECTORY_KEY, "/tmp"); String exportPath = JetspeedResources.getString("psml.export.default.path", TurbineServlet.getRealPath(tmpPath)); if(path == null) { context.put(COPY_TO, exportPath); context.put(COPY_FROM, Profiler.PARAM_USER + File.separator + Profiler.PARAM_ANON + File.separator + Profiler.PARAM_MEDIA_TYPE + File.separator + "html" + File.separator + Profiler.PARAM_PAGE + File.separator + Profiler.FULL_DEFAULT_PROFILE); } else { ProfileLocator tmpLocator = Profiler.createLocator(); tmpLocator.createFromPath(path); Profile profile = Profiler.getProfile(tmpLocator); if (profile != null) { rundata.getUser().setTemp(TEMP_LOCATOR, tmpLocator); context.put("profile", profile); } String categoryName = Profiler.PARAM_GROUP; String categoryValue = tmpLocator.getGroupName(); if (categoryValue == null) { categoryName = Profiler.PARAM_ROLE; categoryValue = tmpLocator.getRoleName(); if (categoryValue == null) { categoryName = Profiler.PARAM_USER; categoryValue = tmpLocator.getUserName(); if (categoryValue == null) { categoryName = Profiler.PARAM_USER; categoryValue = Profiler.PARAM_ANON; } } } context.put(COPY_TO, exportPath + File.separator + tmpLocator.getName()); context.put(COPY_FROM, path); } } else { context.put(COPY_TO, rundata.getUser().getTemp(COPY_TO)); context.put(COPY_FROM, rundata.getUser().getTemp(COPY_FROM)); } } if(mode != null && mode.equals("export_all")) { if (msgid == null) { // get the PSML Root Directory ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance()) .getResources(PsmlManagerService.SERVICE_NAME); String root = serviceConf.getString("root", "/WEB-INF/psml"); context.put(COPY_TO, TurbineServlet.getRealPath(root)); } else { context.put(COPY_TO, rundata.getUser().getTemp(COPY_TO)); } } if(mode != null && mode.equals("import")) { org.apache.jetspeed.om.registry.Registry mediaTypes = Registry.get(Registry.MEDIA_TYPE); context.put("mediaTypes", mediaTypes.listEntryNames()); if (msgid == null) { // get the PSML Root Directory ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance()) .getResources(PsmlManagerService.SERVICE_NAME); String root = serviceConf.getString("root", "/WEB-INF/psml"); root = TurbineServlet.getRealPath(root); if(path == null) { context.put(CATEGORY_NAME, Profiler.PARAM_USER); context.put("categoryValue", Profiler.PARAM_ANON); context.put("copyFrom", root + File.separator + Profiler.PARAM_USER + File.separator + Profiler.PARAM_ANON + File.separator + Profiler.PARAM_MEDIA_TYPE + File.separator + "html" + File.separator + Profiler.PARAM_PAGE + File.separator + Profiler.FULL_DEFAULT_PROFILE); } else { ProfileLocator tmpLocator = Profiler.createLocator(); tmpLocator.createFromPath(path); Profile profile = Profiler.getProfile(tmpLocator); if (profile != null) { rundata.getUser().setTemp(TEMP_LOCATOR, tmpLocator); context.put("profile", profile); } String categoryName = Profiler.PARAM_GROUP; String categoryValue = tmpLocator.getGroupName(); if (categoryValue == null) { categoryName = Profiler.PARAM_ROLE; categoryValue = tmpLocator.getRoleName(); if (categoryValue == null) { categoryName = Profiler.PARAM_USER; categoryValue = tmpLocator.getUserName(); if (categoryValue == null) { categoryName = Profiler.PARAM_USER; categoryValue = Profiler.PARAM_ANON; } } } context.put(CATEGORY_NAME, categoryName); context.put("categoryValue", categoryValue); String filePath = this.mapLocatorToFile(tmpLocator); context.put("copyFrom", root + File.separator + filePath.toString()); } } else { context.put(CATEGORY_NAME, rundata.getUser().getTemp(CATEGORY_NAME)); context.put(CATEGORY_VALUE, rundata.getUser().getTemp(CATEGORY_VALUE)); context.put(COPY_FROM, rundata.getUser().getTemp(COPY_FROM)); } } if(mode != null && mode.equals("import_all")) { if (msgid == null) { // get the PSML Root Directory ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance()) .getResources(PsmlManagerService.SERVICE_NAME); String root = serviceConf.getString("root", "/WEB-INF/psml"); context.put(COPY_FROM, TurbineServlet.getRealPath(root)); } else { context.put(COPY_FROM, rundata.getUser().getTemp(COPY_FROM)); } } } catch (Exception e) { logger.error("Exception", e); rundata.setMessage("Error in PsmlUpdateAction: " + e.toString()); rundata.setStackTrace(StringUtils.stackTrace(e), e); rundata.setScreenTemplate(JetspeedResources.getString("template.error","Error")); } } /** * Database Insert Action for Psml. * * @param rundata The turbine rundata context for this request. * @param context The velocity context for this request. */ public void doInsert(RunData rundata, Context context) throws Exception { Profile profile = null; ProfileLocator locator = null; String categoryName = null; String categoryValue = null; String copyFrom = null; String name = null; try { categoryName = rundata.getParameters().getString("CategoryName"); categoryValue = rundata.getParameters().getString("CategoryValue"); copyFrom = rundata.getParameters().getString("CopyFrom"); name = rundata.getParameters().getString("name"); // //create a new locator and set its values according to users input // locator = Profiler.createLocator(); if (categoryName.equalsIgnoreCase(Profiler.PARAM_GROUP)) { locator.setGroupByName(categoryValue); } else if (categoryName.equalsIgnoreCase(Profiler.PARAM_ROLE)) { locator.setRoleByName(categoryValue); } else if (categoryName.equalsIgnoreCase(Profiler.PARAM_USER)) { locator.setUser(JetspeedSecurity.getUser(categoryValue)); } else { locator.setAnonymous(true); } String tempVar = rundata.getParameters().getString("psml_mediatype"); if (tempVar != null && tempVar.trim().length() > 0) { locator.setMediaType(tempVar); } tempVar = rundata.getParameters().getString("psml_language"); if (tempVar != null && tempVar.trim().length() > 0) { locator.setLanguage(tempVar); } tempVar = rundata.getParameters().getString("psml_country"); if (tempVar != null && tempVar.trim().length() > 0) { locator.setCountry(tempVar); } locator.setName(name); //check if profile to be created already exists if (PsmlManager.getDocument(locator) != null ) throw new EntityExistsException("Profile:"+locator.getPath()+" Already Exists!"); // // validate that its not an 'blank' profile -- not allowed // if (name == null || name.trim().length() == 0) { JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, SecurityConstants.PARAM_MODE_INSERT) .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_INVALID_ENTITY_NAME); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); //save user entered values if (locator != null) rundata.getUser().setTemp(TEMP_LOCATOR, locator); if (categoryName != null) rundata.getUser().setTemp(CATEGORY_NAME, categoryName); if (categoryValue != null) rundata.getUser().setTemp(CATEGORY_VALUE, categoryValue); if (copyFrom != null) rundata.getUser().setTemp(COPY_FROM, copyFrom); return; } // // retrieve the profile to clone // ProfileLocator baseLocator = Profiler.createLocator(); baseLocator.createFromPath(copyFrom); Profile baseProfile = Profiler.getProfile(baseLocator); // // create a new profile // if(baseProfile != null) { PSMLDocument doc = baseProfile.getDocument(); if(doc != null) { Portlets portlets = doc.getPortlets(); Portlets clonedPortlets = (Portlets) SerializationUtils.clone(portlets); org.apache.jetspeed.util.PortletUtils.regenerateIds(clonedPortlets); profile = Profiler.createProfile(locator, clonedPortlets); } else { profile = Profiler.createProfile(locator, null); } setRefreshPsmlFlag(rundata, TRUE); } else { logger.error("Profile listed in Copy From Not Found!"); } } catch (EntityExistsException e) { // log the error msg logger.error("Exception", e); // // dup key found - display error message - bring back to same screen // JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, SecurityConstants.PARAM_MODE_INSERT) .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_ENTITY_ALREADY_EXISTS); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); } catch (Exception e) { // log the error msg logger.error("Exception", e); // // dup key found - display error message - bring back to same screen // JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, SecurityConstants.PARAM_MODE_INSERT) .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_UPDATE_FAILED); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); } // save values that user just entered so they don't have to re-enter if (locator != null) rundata.getUser().setTemp(TEMP_LOCATOR, locator); if (categoryName != null) rundata.getUser().setTemp(CATEGORY_NAME, categoryName); if (categoryValue != null) rundata.getUser().setTemp(CATEGORY_VALUE, categoryValue); if (copyFrom != null) rundata.getUser().setTemp(COPY_FROM, copyFrom); } /** * Delete Psml entry */ public void doDelete(RunData rundata, Context context) throws Exception { try { ProfileLocator locator = (ProfileLocator)rundata.getUser().getTemp(TEMP_LOCATOR); if (locator != null) { Profiler.removeProfile(locator); setRefreshPsmlFlag(rundata, TRUE); } else { logger.error("ProfileLocator not found!"); } } catch(Exception e) { // log the error msg logger.error("Exception", e); // // dup key found - display error message - bring back to same screen // JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, SecurityConstants.PARAM_MODE_DELETE) .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_DELETE_FAILED); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); } } public void setRefreshPsmlFlag(RunData rundata, String value) { rundata.getUser().setTemp(PSML_REFRESH_FLAG, TRUE); } /** * File Export Action for Psml. * * @param rundata The turbine rundata context for this request. * @param context The velocity context for this request. */ public void doExport(RunData rundata, Context context) throws Exception { Profile profile = null; ProfileLocator locator = null; String copyTo = null; String copyFrom = null; try { copyFrom = rundata.getParameters().getString("CopyFrom"); copyTo = rundata.getParameters().getString("CopyTo"); // // retrieve the profile to clone // ProfileLocator baseLocator = Profiler.createLocator(); baseLocator.createFromPath(copyFrom); Profile baseProfile = Profiler.getProfile(baseLocator); // // Export profile // if(baseProfile != null) { PSMLDocument doc = baseProfile.getDocument(); if(doc != null) { if (!this.saveDocument(copyTo,doc)) throw new Exception("Failed to save PSML document"); rundata.addMessage("Profile [" + copyFrom + "] has been saved to disk in [" + copyTo + "]<br>"); } } else { logger.error("Profile listed in Copy From Not Found!"); } } catch (Exception e) { // log the error msg logger.error("Exception", e); // // dup key found - display error message - bring back to same screen // JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, "export") .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_UPDATE_FAILED); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); } // save values that user just entered so they don't have to re-enter if (copyTo != null) rundata.getUser().setTemp(COPY_TO, copyTo); if (copyFrom != null) rundata.getUser().setTemp(COPY_FROM, copyFrom); } /** * File Export All Action for Psml. * * @param rundata The turbine rundata context for this request. * @param context The velocity context for this request. */ public void doExportall(RunData rundata, Context context) throws Exception { String copyTo = null; logger.info("PsmlUpdateAction: Starting export all operation"); try { copyTo = rundata.getParameters().getString("CopyTo"); // // retrieve the profiles to export // Iterator i = Profiler.query(new QueryLocator(QueryLocator.QUERY_ALL)); while (i.hasNext()) { Profile profile = (Profile) i.next(); PSMLDocument doc = profile.getDocument(); if(doc != null) { // Build the fully qualified file name StringBuffer copyToFile = new StringBuffer(copyTo); copyToFile.append(File.separator); if (profile.getGroupName() != null) { copyToFile.append("group"); copyToFile.append(File.separator); copyToFile.append(profile.getGroupName()); copyToFile.append(File.separator); } else if (profile.getRoleName() != null) { copyToFile.append("role"); copyToFile.append(File.separator); copyToFile.append(profile.getRoleName()); copyToFile.append(File.separator); } else if (profile.getUserName() != null) { copyToFile.append("user"); copyToFile.append(File.separator); copyToFile.append(profile.getUserName()); copyToFile.append(File.separator); } if (profile.getMediaType() != null) { copyToFile.append(profile.getMediaType()); copyToFile.append(File.separator); } if (profile.getLanguage() != null) { copyToFile.append(profile.getLanguage()); copyToFile.append(File.separator); } if (profile.getCountry() != null) { copyToFile.append(profile.getCountry()); copyToFile.append(File.separator); } copyToFile.append(profile.getName()); if (!this.saveDocument(copyToFile.toString(), doc)) { logger.error("Failed to save PSML document for [" + profile.getPath()); } else { String msg = "Profile [" + profile.getPath() + "] has been saved to disk in [" + copyToFile.toString() + "]<br>"; logger.info(msg); rundata.addMessage(msg); } } } } catch (Exception e) { // log the error msg logger.error("Exception", e); // // dup key found - display error message - bring back to same screen // JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, "export_all") .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_UPDATE_FAILED); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); } // save values that user just entered so they don't have to re-enter if (copyTo != null) { rundata.getUser().setTemp(COPY_TO, copyTo); } logger.info("PsmlUpdateAction: Ending export all operation"); } /** Save the PSML document on disk to the specififed fileOrUrl * * @param fileOrUrl a String representing either an absolute URL * or an absolute filepath * @param doc the document to save */ private boolean saveDocument(String fileOrUrl, PSMLDocument doc) { boolean success = false; if (doc == null) return false; File f = new File(fileOrUrl); File d = new File(f.getParent()); d.mkdirs(); FileWriter writer = null; try { writer = new FileWriter(f); // create the serializer output format OutputFormat format = new OutputFormat(); format.setIndenting(true); format.setIndent(4); Serializer serializer = new XMLSerializer(writer,format); Marshaller marshaller = new Marshaller(serializer.asDocumentHandler()); marshaller.setMapping(this.loadMapping()); marshaller.marshal(doc.getPortlets()); success = true; } catch (MarshalException e) { logger.error("PSMLUpdateAction: Could not marshal the file " + f.getAbsolutePath(), e); } catch (MappingException e) { logger.error("PSMLUpdateAction: Could not marshal the file " + f.getAbsolutePath(), e); } catch (ValidationException e) { logger.error("PSMLUpdateAction: document "+f.getAbsolutePath() + " is not valid", e); } catch (IOException e) { logger.error("PSMLUpdateAction: Could not save the file " + f.getAbsolutePath(), e); } catch (Exception e) { logger.error("PSMLUpdateAction: Error while saving " + f.getAbsolutePath(), e); } finally { try { writer.close(); } catch (IOException e) { } } return success; } /** * Loads psml mapping file * * @exception Exception */ private Mapping loadMapping() throws Exception { // get configuration parameters from Jetspeed Resources ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance()) .getResources(PsmlManagerService.SERVICE_NAME); // test the mapping file and create the mapping object Mapping mapping = null; String mapFile = serviceConf.getString("mapping","${webappRoot}/WEB-INF/conf/psml-mapping.xml"); mapFile = TurbineServlet.getRealPath( mapFile ); if (mapFile != null) { File map = new File(mapFile); if ( logger.isDebugEnabled() ) { logger.debug( "Loading psml mapping file " + mapFile ); } if (map.exists() && map.isFile() && map.canRead()) { try { mapping = new Mapping(); InputSource is = new InputSource( new FileReader(map) ); is.setSystemId( mapFile ); mapping.loadMapping( is ); } catch (Exception e) { logger.error("Error in psml mapping creation", e); throw new Exception("Error in mapping"); } } else { throw new Exception("PSML Mapping not found or not a file or unreadable: " + mapFile); } } return mapping; } /** * File Import Action for Psml. * * TODO: Implement file upload. * * @param rundata The turbine rundata context for this request. * @param context The velocity context for this request. */ public void doImport(RunData rundata, Context context) throws Exception { Profile profile = null; ProfileLocator locator = null; String categoryName = null; String categoryValue = null; String copyFrom = null; String name = null; try { categoryName = rundata.getParameters().getString("CategoryName"); categoryValue = rundata.getParameters().getString("CategoryValue"); copyFrom = rundata.getParameters().getString("CopyFrom"); name = rundata.getParameters().getString("name"); // //create a new locator and set its values according to users input // locator = Profiler.createLocator(); if (categoryName.equalsIgnoreCase(Profiler.PARAM_GROUP)) { locator.setGroupByName(categoryValue); } else if (categoryName.equalsIgnoreCase(Profiler.PARAM_ROLE)) { locator.setRoleByName(categoryValue); } else if (categoryName.equalsIgnoreCase(Profiler.PARAM_USER)) { locator.setUser(JetspeedSecurity.getUser(categoryValue)); } else { locator.setAnonymous(true); } String tempVar = rundata.getParameters().getString("psml_mediatype"); if (tempVar != null && tempVar.trim().length() > 0) { locator.setMediaType(tempVar); } tempVar = rundata.getParameters().getString("psml_language"); if (tempVar != null && tempVar.trim().length() > 0) { locator.setLanguage(tempVar); } tempVar = rundata.getParameters().getString("psml_country"); if (tempVar != null && tempVar.trim().length() > 0) { locator.setCountry(tempVar); } locator.setName(name); // // validate that its not an 'blank' profile -- not allowed // if (name == null || name.trim().length() == 0) { JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, "import") .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_INVALID_ENTITY_NAME); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); //save user entered values if (locator != null) { rundata.getUser().setTemp(TEMP_LOCATOR, locator); } if (categoryName != null) { rundata.getUser().setTemp(CATEGORY_NAME, categoryName); } if (categoryValue != null) { rundata.getUser().setTemp(CATEGORY_VALUE, categoryValue); } if (copyFrom != null) { rundata.getUser().setTemp(COPY_FROM, copyFrom); } return; } // // Retrieve the document to import // PSMLDocument doc = this.loadDocument(copyFrom); // // create a new profile // if(doc != null) { Portlets portlets = doc.getPortlets(); // // Profiler does not provide update capability - must remove before replacing // if (PsmlManager.getDocument(locator) != null) { Profiler.removeProfile(locator); } Portlets clonedPortlets = (Portlets) SerializationUtils.clone(portlets); org.apache.jetspeed.util.PortletUtils.regenerateIds(clonedPortlets); profile = Profiler.createProfile(locator, clonedPortlets); } else { throw new Exception("Failed to load PSML document from disk"); } rundata.addMessage("Profile for [" + locator.getPath() + "] has been imported from file [" + copyFrom + "]<br>"); setRefreshPsmlFlag(rundata, TRUE); } catch (Exception e) { // log the error msg logger.error("Exception", e); // // dup key found - display error message - bring back to same screen // JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, "import") .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_UPDATE_FAILED); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); } // save values that user just entered so they don't have to re-enter if (locator != null) { rundata.getUser().setTemp(TEMP_LOCATOR, locator); } if (categoryName != null) { rundata.getUser().setTemp(CATEGORY_NAME, categoryName); } if (categoryValue != null) { rundata.getUser().setTemp(CATEGORY_VALUE, categoryValue); } if (copyFrom != null) { rundata.getUser().setTemp(COPY_FROM, copyFrom); } } /** * File Import All Action for Psml. * * * @param rundata The turbine rundata context for this request. * @param context The velocity context for this request. */ public void doImportall(RunData rundata, Context context) throws Exception { String copyFrom = null; try { copyFrom = rundata.getParameters().getString("CopyFrom"); // // Collect all .psml files from the root specified // Vector files = new Vector(); this.collectPsml(files, copyFrom); // // Process each file // for (Iterator it = files.iterator(); it.hasNext(); ) { // If error occurs processing one entry, continue on with the others String path = null; try { String psml = ((File) it.next()).getPath(); path = psml.substring(copyFrom.length() + 1); ProfileLocator locator = this.mapFileToLocator(path); PSMLDocument doc = this.loadDocument(psml); // // create a new profile // if(doc != null) { Portlets portlets = doc.getPortlets(); // // Profiler does not provide update capability - must remove before replacing // if (PsmlManager.getDocument(locator) != null) { Profiler.removeProfile(locator); } Profiler.createProfile(locator, portlets); } else { throw new Exception("Failed to load PSML document [" + psml + "] from disk"); } rundata.addMessage("Profile for [" + locator.getPath() + "] has been imported from file [" + psml + "]<br>"); setRefreshPsmlFlag(rundata, TRUE); } catch (Exception ouch) { logger.error("Exception", ouch); rundata.addMessage("ERROR importing file [" + path + "]: " + ouch.toString() + "<br>"); } } } catch (Exception e) { // log the error msg logger.error("Exception", e); // // dup key found - display error message - bring back to same screen // JetspeedLink link = JetspeedLinkFactory.getInstance(rundata); DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE) .addPathInfo(SecurityConstants.PARAM_MODE, "import_all") .addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_UPDATE_FAILED); JetspeedLinkFactory.putInstance(link); rundata.setRedirectURI(duri.toString()); } // save values that user just entered so they don't have to re-enter if (copyFrom != null) { rundata.getUser().setTemp(COPY_FROM, copyFrom); } } /** * This method recursively collect all .psml documents starting at the given root * * @param v Vector to put the file into * @param root Root directory for import */ private void collectPsml(Vector v, String root) { File dir = new File(root); File[] files = dir.listFiles(); for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { collectPsml(v, files[i].getPath()); } else if (files[i].isFile() && files[i].getPath().endsWith(".psml")) { v.add(files[i]); } } } /** * Creates profile locator from a given path in the format: * * user/<name>/<mediaType>/<language>/<country>/<page>/ * * group/ "" * role/ "" * * @param path The formatted profiler path string. * @param path fully qualified .psml file name * @return profile locator */ private ProfileLocator mapFileToLocator(String path) throws Exception { if (logger.isDebugEnabled()) { logger.debug("PsmlUpdateAction.createFromPath: processing path = " + path); } ProfileLocator result = Profiler.createLocator(); // Tokenize the file path into elements StringTokenizer tok = new StringTokenizer(path, File.separator); // Load path elements into a vector for random access Vector tokens = new Vector(); while (tok.hasMoreTokens()) { tokens.add(tok.nextToken()); } // Assume that 1st element is the profile type (user|role|group) and 2nd is the name if (tokens.size() > 1) { String type = (String) tokens.elementAt(0); String name = (String) tokens.elementAt(1); if (type.equals(Profiler.PARAM_USER)) { result.setUser(JetspeedSecurity.getUser(name)); } else if (type.equals(Profiler.PARAM_GROUP)) { result.setGroup(JetspeedSecurity.getGroup(name)); } else if (type.equals(Profiler.PARAM_ROLE)) { result.setRole(JetspeedSecurity.getRole(name)); } } // Assume that the last element is the page name if (tokens.size() > 0) { result.setName((String) tokens.lastElement()); } // Based on the number of path elements set the other profile attributes switch (tokens.size()) { case 3: // user|role|group/name/page.psml break; case 4: // user|role|group/name/media-type/page.psml result.setMediaType((String) tokens.elementAt(2)); break; case 5: // user|role|group/name/media-type/language/page.psml result.setMediaType((String) tokens.elementAt(2)); result.setLanguage((String) tokens.elementAt(3)); break; case 6: // user|role|group/name/media-type/language/country/page.psml result.setMediaType((String) tokens.elementAt(2)); result.setLanguage((String) tokens.elementAt(3)); result.setCountry((String) tokens.elementAt(4)); break; default: throw new Exception("Path must contain 3 to 6 elements: [" + path + "], and the size was: " + tokens.size()); } return result; } /** * Maps a ProfileLocator to a file. * * @param locator The profile locator describing the PSML resource to be found. * @return the String path of the file. */ private String mapLocatorToFile(ProfileLocator locator) { StringBuffer path = new StringBuffer(); // move the base dir is either user or role is specified Role role = locator.getRole(); Group group = locator.getGroup(); JetspeedUser user = locator.getUser(); if (user != null) { path.append(Profiler.PARAM_USER); String name = user.getUserName(); if (null != name && name.length() > 0) { path.append(File.separator) .append(name); } } else if (group != null) { path.append(Profiler.PARAM_GROUP); String name = group.getName(); if (null != name && name.length() > 0) { path.append(File.separator) .append(name); } } else if (null != role) { path.append(Profiler.PARAM_ROLE); String name = role.getName(); if (null != name && name.length() > 0) { path.append(File.separator) .append(name); } } // Media if (null != locator.getMediaType()) { path.append(File.separator) .append(locator.getMediaType()); } // Language if (null != locator.getLanguage()) { path.append(File.separator) .append(locator.getLanguage()); } // Country if (null != locator.getCountry()) { path.append(File.separator) .append(locator.getCountry()); } // Resource Name if (null != locator.getName()) { if (!(locator.getName().endsWith(Profiler.DEFAULT_EXTENSION))) { path.append(File.separator) .append(locator.getName()).append(Profiler.DEFAULT_EXTENSION); } else { path.append(File.separator) .append(locator.getName()); } } else { path.append(File.separator) .append(Profiler.FULL_DEFAULT_PROFILE); } return path.toString(); } /** * Load a PSMLDOcument from disk * * @param fileOrUrl a String representing either an absolute URL or an * absolute filepath */ private PSMLDocument loadDocument(String fileOrUrl) { PSMLDocument doc = null; if (fileOrUrl != null) { // we'll assume the name is the the location of the file File f = null; f = new File(fileOrUrl); if (!f.exists()) { return null; } doc = new BasePSMLDocument(); doc.setName(fileOrUrl); // now that we have a file reference, try to load the serialized PSML Portlets portlets = null; FileReader reader = null; try { reader = new FileReader(f); Unmarshaller unmarshaller = new Unmarshaller(this.loadMapping()); portlets = (Portlets) unmarshaller.unmarshal(reader); doc.setPortlets(portlets); } catch (IOException e) { logger.error("PSMLUpdateAction: Could not load the file " + f.getAbsolutePath(), e); } catch (MarshalException e) { logger.error("PSMLUpdateAction: Could not unmarshal the file " + f.getAbsolutePath(), e); } catch (MappingException e) { logger.error("PSMLUpdateAction: Could not unmarshal the file " + f.getAbsolutePath(), e); } catch (ValidationException e) { logger.error("PSMLUpdateAction: document " + f.getAbsolutePath() + " is not valid", e); } catch (Exception e) { logger.error("PSMLUpdateAction: Error while loading " + f.getAbsolutePath(), e); } finally { try { reader.close(); } catch (IOException e) { } } } return doc; } }