0001: /*
0002: * (C) Copyright 2000 - 2005 Nabh Information Systems, Inc.
0003: *
0004: * This program is free software; you can redistribute it and/or
0005: * modify it under the terms of the GNU General Public License
0006: * as published by the Free Software Foundation; either version 2
0007: * of the License, or (at your option) any later version.
0008: *
0009: * This program is distributed in the hope that it will be useful,
0010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0012: * GNU General Public License for more details.
0013: *
0014: * You should have received a copy of the GNU General Public License
0015: * along with this program; if not, write to the Free Software
0016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0017: *
0018: */
0019: package com.nabhinc.portal.api;
0020:
0021: import java.io.File;
0022: import java.io.FileInputStream;
0023: import java.io.FileNotFoundException;
0024: import java.io.FileOutputStream;
0025: import java.io.FileReader;
0026: import java.io.FileWriter;
0027: import java.io.IOException;
0028: import java.io.InputStream;
0029: import java.io.InputStreamReader;
0030: import java.io.LineNumberReader;
0031: import java.io.OutputStreamWriter;
0032: import java.io.StringWriter;
0033: import java.io.UnsupportedEncodingException;
0034: import java.rmi.RemoteException;
0035: import java.util.ArrayList;
0036: import java.util.Collection;
0037: import java.util.Collections;
0038: import java.util.GregorianCalendar;
0039: import java.util.HashMap;
0040: import java.util.List;
0041: import java.util.Map;
0042: import java.util.TreeMap;
0043: import java.util.Vector;
0044:
0045: import javax.servlet.ServletException;
0046: import javax.servlet.http.HttpServletRequest;
0047: import javax.xml.bind.JAXBContext;
0048: import javax.xml.bind.JAXBException;
0049: import javax.xml.bind.Marshaller;
0050: import javax.xml.bind.Unmarshaller;
0051:
0052: import com.nabhinc.condition.OwnerCondition;
0053: import com.nabhinc.portal.model.PortalApplication;
0054: import com.nabhinc.portal.model.PortalConfiguration;
0055: import com.nabhinc.portal.model.UserPreferences;
0056: import com.nabhinc.spi.EntityExistsException;
0057: import com.nabhinc.util.IOUtil;
0058: import com.nabhinc.util.ImageUtil;
0059: import com.nabhinc.util.StringUtil;
0060: import com.nabhinc.ws.core.WebServiceException;
0061: import com.nabhinc.ws.core.WebServiceSecurityException;
0062: import com.nabhinc.ws.server.Current;
0063: import com.nabhinc.ws.server.RequestContext;
0064: import com.nabhinc.ws.server.ServerObjectConfig;
0065: import com.nabhinc.ws.service.core.BaseJavaWebService;
0066:
0067: /**
0068: *
0069: *
0070: * @author Padmanabh Dabke (c)
0071: * 2005 Nabh Information Systems, Inc. All Rights Reserved.
0072: */
0073: public class PortalInformationStoreFileImpl extends BaseJavaWebService
0074: implements PortalInformationStore {
0075:
0076: public static final String PSITE_DATA_DIR = "/psite_data";
0077:
0078: public static final String DEFAULT_PORTAL_APP_DIR = "/WEB-INF/psites";
0079:
0080: public static final String DEFAULT_USER_PREFS_DIR = "/WEB-INF/user_prefs";
0081:
0082: public static final String PORTAL_XML_PATH = "/WEB-INF/portal.xml";
0083:
0084: public static final String PORTLET_XML_PATH = "/WEB-INF/portlet.xml";
0085:
0086: private static final String JAXB_PACKAGE_PATH = "com.nabhinc.condition:com.nabhinc.portal.model:com.nabhinc.portlet.htmlblock:com.nabhinc.portlet.feed:com.nabhinc.portlet.image";//:com.nabhinc.portlet.thingtang";
0087:
0088: public static final String CONFIG_DIR = "/config";
0089: public static final String VERSION_DIR = "versions";
0090: public static final String VERSION_FILE_PREFIX = "v_";
0091: public static final String LOCK_FILE = ".lock";
0092: public static final String MEMBER_FILE = ".members";
0093: public static final String OWNER_FILE = ".owner";
0094: public static final String DEFAULT_OWNER = "admin";
0095:
0096: private String pisfiCharSet = "UTF-8";
0097:
0098: private String pisfiPortalAppDir = DEFAULT_PORTAL_APP_DIR;
0099:
0100: private String pisfiPortalAppDirAbsPath = null;
0101:
0102: private String pisfiUserPrefsDir = DEFAULT_USER_PREFS_DIR;
0103:
0104: private String pisfiUserPrefsDirAbsPath = null;
0105:
0106: private String pisfiJAXBPackagePath = null;
0107:
0108: private transient JAXBContext pisfiJAXBContext = null;
0109:
0110: private transient HashMap<String, PortalApplication> pisfiPortalAppMap = new HashMap<String, PortalApplication>();
0111:
0112: private transient HashMap<String, String[]> pisfiMembersMap = new HashMap<String, String[]>();
0113:
0114: private transient HashMap<String, String[]> pisfiOwnerAppPathMap = new HashMap<String, String[]>();
0115:
0116: public void init(ServerObjectConfig config)
0117: throws WebServiceException {
0118: super .init(config);
0119: if (pisfiPortalAppDirAbsPath == null) {
0120: setAbsoluteDirectory();
0121: }
0122: if (pisfiUserPrefsDirAbsPath == null)
0123: setPrefsAbsoluteDirectory();
0124:
0125: String jaxbPackagePath = JAXB_PACKAGE_PATH;
0126: if (this .pisfiJAXBPackagePath != null)
0127: jaxbPackagePath = this .pisfiJAXBPackagePath;
0128: try {
0129: this .pisfiJAXBContext = JAXBContext
0130: .newInstance(jaxbPackagePath);
0131: } catch (Exception e) {
0132: throw new WebServiceException(
0133: "Failed to create JAXBContext.", e);
0134: }
0135: }
0136:
0137: public String getJAXBPackagePath() {
0138: return this .pisfiJAXBPackagePath;
0139: }
0140:
0141: public void setJAXBPackagePath(String p) throws JAXBException {
0142: this .pisfiJAXBPackagePath = p;
0143: this .pisfiJAXBContext = JAXBContext.newInstance(p);
0144: }
0145:
0146: public String getPortalAppDir() {
0147: return pisfiPortalAppDir;
0148: }
0149:
0150: public void setPortalAppDir(String newDir)
0151: throws WebServiceException {
0152: pisfiPortalAppDir = newDir;
0153: setAbsoluteDirectory();
0154: }
0155:
0156: public String getUserPrefsDir() {
0157: return pisfiUserPrefsDir;
0158: }
0159:
0160: public void setUserPrefsDir(String newDir)
0161: throws WebServiceException {
0162: pisfiUserPrefsDir = newDir;
0163: setPrefsAbsoluteDirectory();
0164: }
0165:
0166: private void setAbsoluteDirectory() throws WebServiceException {
0167: pisfiPortalAppDirAbsPath = soiServerContext
0168: .getRealPath(pisfiPortalAppDir);
0169: File f = new File(pisfiPortalAppDirAbsPath);
0170: if (!f.exists()) {
0171: if (!f.mkdirs())
0172: throw new WebServiceException(
0173: "Failed to create root directory for storing portal sites.");
0174: }
0175: }
0176:
0177: private void setPrefsAbsoluteDirectory() throws WebServiceException {
0178: pisfiUserPrefsDirAbsPath = soiServerContext
0179: .getRealPath(pisfiUserPrefsDir);
0180: File f = new File(pisfiUserPrefsDirAbsPath);
0181: if (!f.exists()) {
0182: if (!f.mkdirs())
0183: throw new WebServiceException(
0184: "Failed to create root directory for storing user preferences.");
0185: }
0186: }
0187:
0188: public String getCharSet() {
0189: return pisfiCharSet;
0190: }
0191:
0192: public void setCharSet(String newCharSet) {
0193: pisfiCharSet = newCharSet;
0194: }
0195:
0196: public synchronized PortalApplication getPortalApplication(
0197: String path) throws WebServiceSecurityException,
0198: RemoteException {
0199: return getPortalApplicationHelper(path, true);
0200: }
0201:
0202: public PortalApplication getPortalApplicationHelper(String path,
0203: boolean getFromCache) throws WebServiceSecurityException,
0204: RemoteException {
0205:
0206: PortalApplication app = retrievePortalApplication(path,
0207: getFromCache);
0208: if (app != null) {
0209: RequestContext reqContext = Current.getRequestContext();
0210: HttpServletRequest req = reqContext.getHttpServletRequest();
0211: try {
0212: if (!app.isViewable(req)) {
0213: throw new WebServiceSecurityException(
0214: "You are not permitted to view this psite.");
0215: }
0216: } catch (ServletException e) {
0217: throw new RemoteException(
0218: "Could not check app permissions.", e);
0219: }
0220: }
0221: return app;
0222: }
0223:
0224: private PortalApplication retrievePortalApplication(
0225: String portalPath, boolean getFromCache)
0226: throws RemoteException {
0227: PortalApplication app = null;
0228: if (getFromCache)
0229: app = getCachedApp(portalPath);
0230: if (app == null) {
0231:
0232: InputStream is = getPortalAppInputStream(portalPath);
0233: if (is == null)
0234: return null;
0235:
0236: try {
0237: app = unmarshalPortalApplication(is);
0238: app.setPath(portalPath);
0239: if (getFromCache)
0240: cacheApp(app);
0241:
0242: } catch (JAXBException e) {
0243: throw new RemoteException(
0244: "Failed to unmarshal portal application.", e);
0245: } catch (UnsupportedEncodingException e) {
0246: throw new RemoteException(
0247: "Failed to unmarshal portal application.", e);
0248: } finally {
0249: try {
0250: if (is != null)
0251: is.close();
0252: } catch (Exception e) {
0253: }
0254: }
0255: }
0256: return app;
0257: }
0258:
0259: public synchronized void lockPortalApplication(String appPath)
0260: throws EntityLockedException, WebServiceSecurityException,
0261: RemoteException {
0262: RequestContext reqContext = Current.getRequestContext();
0263: HttpServletRequest req = reqContext.getHttpServletRequest();
0264: String currentUser = req.getRemoteUser();
0265: PortalApplication app = getPortalApplication(appPath);
0266: if (app == null)
0267: return;
0268: try {
0269: if (!app.isAdminable(req) && !app.isEditable(req))
0270: throw new WebServiceSecurityException(
0271: "You cannot lock this psite since you do not have edit priviledges.");
0272: } catch (ServletException e1) {
0273: throw new RemoteException(
0274: "Could not check app permissions.", e1);
0275: }
0276:
0277: try {
0278: String currentLock = getCurrentLock(appPath);
0279: if (currentLock == null) {
0280: writeLock(appPath, currentUser);
0281: app.setLockedBy(currentUser);
0282: } else if (currentUser.equals(currentLock)) {
0283: return;
0284: } else
0285: throw new EntityLockedException(currentLock);
0286: } catch (IOException e) {
0287: throw new RemoteException("Failed to write lock file.", e);
0288: }
0289: }
0290:
0291: public synchronized void unlockPortalApplication(String appPath)
0292: throws EntityLockedException, WebServiceSecurityException,
0293: RemoteException {
0294: RequestContext reqContext = Current.getRequestContext();
0295: HttpServletRequest req = reqContext.getHttpServletRequest();
0296: String currentUser = req.getRemoteUser();
0297: PortalApplication app = getPortalApplication(appPath);
0298: if (app == null)
0299: return;
0300: boolean isAdminable = false;
0301: try {
0302: isAdminable = app.isAdminable(req);
0303: if (!isAdminable && !app.isEditable(req))
0304: throw new WebServiceSecurityException(
0305: "You cannot unlock this psite since you do not have edit priviledges.");
0306: } catch (ServletException e1) {
0307: throw new RemoteException(
0308: "Could not check app permissions.", e1);
0309: }
0310: try {
0311: String lockedBy = getCurrentLock(appPath);
0312: if (lockedBy == null)
0313: return;
0314: if (!lockedBy.equals(currentUser) && (!isAdminable))
0315: throw new EntityLockedException(lockedBy);
0316: removeLock(appPath);
0317: app.setLockedBy(null);
0318: } catch (IOException e) {
0319: throw new RemoteException("Lock removal failed.", e);
0320: }
0321: }
0322:
0323: public synchronized void setPortalApplicationMembers(
0324: String appPath, String[] members)
0325: throws WebServiceSecurityException, RemoteException {
0326: RequestContext reqContext = Current.getRequestContext();
0327: HttpServletRequest req = reqContext.getHttpServletRequest();
0328: PortalApplication app = getPortalApplication(appPath);
0329: if (app == null)
0330: return;
0331: try {
0332: if (!app.isAdminable(req))
0333: throw new WebServiceSecurityException(
0334: "You cannot assign memebers to this psite since you do not have admin priviledges.");
0335: } catch (ServletException e1) {
0336: throw new RemoteException(
0337: "Could not check app permissions.", e1);
0338: }
0339:
0340: try {
0341: if (members == null || members.length == 0) {
0342: removeMembers(appPath);
0343: } else {
0344: writeMembers(appPath, members);
0345: cacheMembers(appPath, members);
0346: }
0347: } catch (IOException e) {
0348: throw new RemoteException("Failed to write lock file.", e);
0349: }
0350: }
0351:
0352: public synchronized String[] getPortalApplicationMembers(
0353: String appPath) throws RemoteException {
0354: String[] members = getMembersFromCache(appPath);
0355: if (members != null)
0356: return members;
0357: try {
0358: return readMembers(appPath);
0359: } catch (IOException e) {
0360: throw new RemoteException("Error in reading app members.",
0361: e);
0362: }
0363:
0364: }
0365:
0366: public synchronized PortalApplication[] getUserPortalApplications()
0367: throws WebServiceSecurityException, RemoteException {
0368: RequestContext reqContext = Current.getRequestContext();
0369: HttpServletRequest req = reqContext.getHttpServletRequest();
0370: String userName = req.getRemoteUser();
0371: if (userName == null)
0372: return new PortalApplication[0];
0373: String[] appPaths = getAppPathsFromCache(userName);
0374: PortalApplication[] apps = null;
0375: try {
0376: if (appPaths == null) {
0377: appPaths = getOwnedApps(userName);
0378: cacheAppPaths(userName, appPaths);
0379: }
0380: apps = new PortalApplication[appPaths.length];
0381: for (int i = 0; i < appPaths.length; i++) {
0382: apps[i] = getPortalApplication(appPaths[i]);
0383: }
0384: return apps;
0385: } catch (IOException e) {
0386: throw new RemoteException("Failed to read owner files.", e);
0387: }
0388: }
0389:
0390: public synchronized boolean isMemberOf(String userName,
0391: String appPath) throws RemoteException {
0392: if (userName == null)
0393: return false;
0394: String[] members = getPortalApplicationMembers(appPath);
0395: if (members == null)
0396: return false;
0397: for (int i = 0; i < members.length; i++) {
0398: if (members[i].equals(userName))
0399: return true;
0400: }
0401: return false;
0402: }
0403:
0404: public synchronized void deletePortalApplication(String appPath)
0405: throws WebServiceSecurityException, RemoteException {
0406: if (appPath == null || appPath.equals(""))
0407: return;
0408: RequestContext reqContext = Current.getRequestContext();
0409: HttpServletRequest req = reqContext.getHttpServletRequest();
0410: PortalApplication app = getPortalApplication(appPath);
0411: if (app == null)
0412: return;
0413: try {
0414: if (!app.isAdminable(req))
0415: throw new WebServiceSecurityException(
0416: "You cannot delete this psite since you do not have admin priviledges.");
0417: } catch (ServletException e1) {
0418: throw new RemoteException(
0419: "Could not check app permissions.", e1);
0420: }
0421: String appFilePath = computeAbsoluteAppFilePath(appPath);
0422: File f = new File(appFilePath);
0423: if (f.exists()) {
0424: f = f.getParentFile().getParentFile();
0425: IOUtil.deleteDirectory(f);
0426: }
0427: uncacheApp(appPath);
0428: uncacheAppPaths(app.getOwnerName());
0429: }
0430:
0431: public synchronized void deletePortalApplicationVersions(
0432: String appPath, int[] versions)
0433: throws WebServiceSecurityException, RemoteException {
0434: if (appPath == null)
0435: return;
0436: RequestContext reqContext = Current.getRequestContext();
0437: HttpServletRequest req = reqContext.getHttpServletRequest();
0438: PortalApplication app = getPortalApplication(appPath);
0439: if (app == null)
0440: return;
0441: try {
0442: if (!app.isAdminable(req))
0443: throw new WebServiceSecurityException(
0444: "You cannot delete versions since you do not have admin priviledges.");
0445: } catch (ServletException e1) {
0446: throw new RemoteException(
0447: "Could not check app permissions.", e1);
0448: }
0449: String appFilePath = computeAbsoluteAppFilePath(appPath);
0450: File f = new File(appFilePath);
0451: File versionDir = new File(f.getParentFile(), VERSION_DIR);
0452: for (int i = 0; i < versions.length; i++) {
0453: File versionFile = new File(versionDir,
0454: getVersionFileName(versions[i]));
0455: versionFile.delete();
0456: }
0457: }
0458:
0459: private synchronized void revertPortalApplication(
0460: PortalApplication oldPortalApp, String portalPath)
0461: throws WebServiceSecurityException, EntityLockedException,
0462: RemoteException {
0463: String path = computeAbsoluteAppFilePath(oldPortalApp.getPath());
0464: File f = new File(path);
0465:
0466: if (f.exists() && !f.canWrite()) {
0467: throw new RemoteException(
0468: "Portal app file is not writable.");
0469: }
0470:
0471: OutputStreamWriter w = null;
0472: try {
0473: RequestContext reqContext = Current.getRequestContext();
0474: HttpServletRequest req = reqContext.getHttpServletRequest();
0475: String currentUser = req.getRemoteUser();
0476: PortalApplication currentPortalApp = getPortalApplication(portalPath);
0477: if ((!currentPortalApp.isAdminable(req))
0478: && (!currentPortalApp.isEditable(req))) {
0479: throw new WebServiceSecurityException(
0480: "Operation not permitted.");
0481: }
0482:
0483: String lockedBy = currentPortalApp.getLockedBy();
0484: if (lockedBy != null && (!lockedBy.equals(currentUser))) {
0485: throw new EntityLockedException(lockedBy);
0486: }
0487:
0488: VersionInfo vInfo = oldPortalApp.getVersionInfo();
0489: if (vInfo == null) {
0490: vInfo = VersionInfo.create(req);
0491: }
0492: //vInfo.setVersionNumber (getLastVersionNumber(portalPath)+1);
0493: vInfo.setVersionNumber(currentPortalApp.getVersionInfo()
0494: .getVersionNumber() + 1);
0495: vInfo.setCreationTime(GregorianCalendar.getInstance());
0496: oldPortalApp.setVersionInfo(vInfo);
0497:
0498: w = new OutputStreamWriter(new FileOutputStream(f),
0499: pisfiCharSet);
0500: Marshaller m = this .pisfiJAXBContext.createMarshaller();
0501: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
0502: m.marshal(oldPortalApp, w);
0503: w.flush();
0504: w.close();
0505: w = null;
0506:
0507: // uncacheApp will mark the old app stale if it is different than the current app.
0508: uncacheApp(portalPath);
0509: cacheApp(oldPortalApp);
0510:
0511: //} catch (FileNotFoundException e) {
0512: // throw new RemoteException("Invalid app path: " + portalApp.getPath(), e);
0513: } catch (IOException e) {
0514: throw new RemoteException("Failed to save app file.", e);
0515: } catch (JAXBException e) {
0516: throw new RemoteException(
0517: "Failed to marshal portal application.", e);
0518: } catch (ServletException e) {
0519: throw new RemoteException(
0520: "Could not check app permissions.", e);
0521: } finally {
0522: try {
0523: if (w != null)
0524: w.close();
0525: } catch (Exception e) {
0526: }
0527: }
0528: }
0529:
0530: public synchronized void savePortalApplication(
0531: PortalApplication portalApp, boolean isCreateVersionFile)
0532: throws WebServiceSecurityException, EntityLockedException,
0533: RemoteException {
0534: String path = computeAbsoluteAppFilePath(portalApp.getPath());
0535: File f = new File(path);
0536:
0537: if (f.exists() && !f.canWrite()) {
0538: throw new RemoteException(
0539: "Portal app file is not writable.");
0540: }
0541:
0542: OutputStreamWriter w = null;
0543: try {
0544: RequestContext reqContext = Current.getRequestContext();
0545: HttpServletRequest req = reqContext.getHttpServletRequest();
0546: String currentUser = req.getRemoteUser();
0547: PortalApplication oldPortalApp = getPortalApplication(portalApp
0548: .getPath());
0549: if ((!oldPortalApp.isAdminable(req))
0550: && (!oldPortalApp.isEditable(req))) {
0551: throw new WebServiceSecurityException(
0552: "Operation not permitted.");
0553: }
0554: String lockedBy = oldPortalApp.getLockedBy();
0555: if (lockedBy != null && (!lockedBy.equals(currentUser))) {
0556: throw new EntityLockedException(lockedBy);
0557: }
0558:
0559: VersionInfo vInfo = oldPortalApp.getVersionInfo();
0560: if (vInfo == null) {
0561: vInfo = VersionInfo.create(req);
0562: vInfo
0563: .setVersionNumber(VersionInfo.INITIAL_VERSION_NUMBER);
0564: }
0565:
0566: if (isCreateVersionFile) {
0567: copyVersionFile(f, vInfo);
0568: vInfo = VersionInfo.create(req);
0569: VersionInfo oldVersionInfo = portalApp.getVersionInfo();
0570: int versionNum = VersionInfo.INITIAL_VERSION_NUMBER;
0571: if (oldVersionInfo != null)
0572: versionNum = oldVersionInfo.getVersionNumber() + 1;
0573: vInfo.setVersionNumber(versionNum);
0574: }
0575:
0576: portalApp.setVersionInfo(vInfo);
0577:
0578: w = new OutputStreamWriter(new FileOutputStream(f),
0579: pisfiCharSet);
0580: Marshaller m = this .pisfiJAXBContext.createMarshaller();
0581: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
0582: m.marshal(portalApp, w);
0583: w.flush();
0584: w.close();
0585: w = null;
0586:
0587: // uncacheApp will mark the old app stale if it is different than the current app.
0588: uncacheApp(portalApp.getPath());
0589: cacheApp(portalApp);
0590: writeOwner(portalApp.getPath(), portalApp.getOwnerName());
0591:
0592: } catch (FileNotFoundException e) {
0593: throw new RemoteException("Invalid app path: "
0594: + portalApp.getPath(), e);
0595: } catch (IOException e) {
0596: throw new RemoteException("Failed to save app file.", e);
0597: } catch (JAXBException e) {
0598: throw new RemoteException(
0599: "Failed to marshal portal application.", e);
0600: } catch (ServletException e) {
0601: throw new RemoteException(
0602: "Could not check app permissions.", e);
0603: } finally {
0604: try {
0605: if (w != null)
0606: w.close();
0607: } catch (Exception e) {
0608: }
0609: }
0610: }
0611:
0612: private String getVersionFileName(int versionNum) {
0613: return VERSION_FILE_PREFIX + versionNum + ".xml";
0614: }
0615:
0616: private synchronized void copyVersionFile(File portalAppFile,
0617: VersionInfo vInfo) throws IOException {
0618: File versionDir = new File(portalAppFile.getParentFile(),
0619: VERSION_DIR);
0620: versionDir.mkdir();
0621: IOUtil.copyFile(portalAppFile, new File(versionDir,
0622: getVersionFileName(vInfo.getVersionNumber())));
0623: }
0624:
0625: public synchronized PortalApplication createPortalApplication(
0626: String appPath, String preferredTemplatePath)
0627: throws RemoteException, WebServiceSecurityException,
0628: OrphanException, EntityExistsException {
0629: if (appPath == null)
0630: throw new IllegalArgumentException(
0631: "Psite path cannot be null.");
0632: String path = computeAbsoluteAppFilePath(appPath);
0633:
0634: File f = new File(path);
0635: if (f.exists()) {
0636: throw new EntityExistsException();
0637: }
0638:
0639: RequestContext reqContext = Current.getRequestContext();
0640: HttpServletRequest req = reqContext.getHttpServletRequest();
0641: String userName = req.getRemoteUser();
0642: if (userName == null)
0643: throw new WebServiceSecurityException(
0644: "You must be logged in to create a new psite.");
0645: String parentPath = StringUtil.extractParentPath(appPath);
0646: PortalApplication parentApp = getPortalApplication(parentPath);
0647: PortalApplication portalApp = null;
0648: OutputStreamWriter w = null;
0649:
0650: if (parentApp == null)
0651: throw new OrphanException();
0652: try {
0653: if (parentPath.equals("/my")) {
0654: if (!appPath.equals("/my/" + req.getRemoteUser()))
0655: throw new WebServiceSecurityException(
0656: "Operation not permitted.");
0657: } else {
0658: if (!parentApp.isPsiteCreatable(req))
0659: throw new WebServiceSecurityException(
0660: "Operation not permitted.");
0661: }
0662: String templatePath = "/templates"
0663: + StringUtil.extractParentPath(appPath);
0664: if (portalApplicationExists(templatePath))
0665: portalApp = getPortalApplicationHelper(templatePath,
0666: false);
0667: else if (preferredTemplatePath != null) {
0668: portalApp = getPortalApplicationHelper(
0669: preferredTemplatePath, false);
0670: templatePath = preferredTemplatePath;
0671: } else {
0672: portalApp = getPortalApplicationHelper("/templates",
0673: false);
0674: templatePath = "/templates";
0675: }
0676: portalApp.setPath(appPath);
0677:
0678: portalApp.setOwnerName(req.getRemoteUser());
0679: portalApp.setVersionInfo(VersionInfo.create(req));
0680: portalApp.setCreatedBy(req.getRemoteUser());
0681: portalApp.setCreationTime(GregorianCalendar.getInstance());
0682: portalApp.setCreationIP(req.getRemoteAddr());
0683: if ("/my".equals(parentPath))
0684: portalApp.setViewPermission(new OwnerCondition());
0685: File psiteDataDir = f.getParentFile();
0686: psiteDataDir.mkdirs();
0687: /*
0688: File origConfigDir = new File(new File(computeAbsoluteAppFilePath(templatePath)).getParentFile(), "config");
0689: if (origConfigDir.exists()) {
0690: IOUtil.copyDirectory(origConfigDir, new File(psiteDataDir, "config"));
0691: }
0692: */
0693: w = new OutputStreamWriter(new FileOutputStream(f),
0694: pisfiCharSet);
0695: Marshaller m = this .pisfiJAXBContext.createMarshaller();
0696: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
0697: m.marshal(portalApp, w);
0698: w.flush();
0699: w.close();
0700: w = null;
0701: File versionDir = new File(psiteDataDir, VERSION_DIR);
0702: versionDir.mkdir();
0703: IOUtil
0704: .copyFile(
0705: f,
0706: new File(
0707: versionDir,
0708: this
0709: .getVersionFileName(VersionInfo.INITIAL_VERSION_NUMBER)));
0710: portalApp.setLockedBy(getCurrentLock(appPath));
0711: cacheApp(portalApp);
0712: uncacheAppPaths(userName);
0713: return portalApp;
0714: } catch (FileNotFoundException e) {
0715: throw new RemoteException("Invalid app path: "
0716: + portalApp.getPath(), e);
0717: } catch (IOException e) {
0718: throw new RemoteException("Failed to save app file.", e);
0719: } catch (JAXBException e) {
0720: throw new RemoteException(
0721: "Failed to unmarshal portal application.", e);
0722: } catch (ServletException e) {
0723: throw new RemoteException(
0724: "Could not check app permissions.", e);
0725: } finally {
0726: try {
0727: if (w != null)
0728: w.close();
0729: } catch (Exception e) {
0730: }
0731: }
0732:
0733: }
0734:
0735: public synchronized boolean portalApplicationExists(String path)
0736: throws WebServiceSecurityException, RemoteException {
0737: return getPortalApplication(path) != null;
0738: }
0739:
0740: public synchronized void replacePortalApplicationWithVersion(
0741: String appPath, int versionNum)
0742: throws WebServiceSecurityException, RemoteException {
0743: RequestContext reqContext = Current.getRequestContext();
0744: HttpServletRequest req = reqContext.getHttpServletRequest();
0745: PortalApplication app = getPortalApplication(appPath);
0746: if (app == null)
0747: return;
0748:
0749: try {
0750: if (!app.isAdminable(req))
0751: throw new WebServiceSecurityException(
0752: "You do not have admin priviledges.");
0753: } catch (ServletException e1) {
0754: throw new RemoteException(
0755: "Could not check app permissions.", e1);
0756: }
0757: String path = computeAbsoluteAppFilePath(appPath);
0758: File f = new File(path);
0759: File versionDir = new File(f.getParentFile(), VERSION_DIR);
0760: FileInputStream fis = null;
0761: try {
0762: removeLock(appPath);
0763: copyVersionFile(f, app.getVersionInfo()); // backup current config
0764: fis = new FileInputStream(new File(versionDir, this
0765: .getVersionFileName(versionNum)));
0766: PortalApplication portalApp = unmarshalPortalApplication(fis);
0767: try {
0768: revertPortalApplication(portalApp, appPath);
0769: } catch (EntityLockedException e) {
0770: }
0771: } catch (FileNotFoundException e) {
0772: throw new RemoteException(
0773: "Failed to unmarshal portal application.", e);
0774: } catch (IOException e) {
0775: throw new RemoteException("Failed to remove lock.", e);
0776: } catch (JAXBException e) {
0777: throw new RemoteException(
0778: "Failed to unmarshal portal application.", e);
0779: } finally {
0780: if (fis != null)
0781: try {
0782: fis.close();
0783: } catch (IOException e) { /* Ignore */
0784: }
0785: }
0786:
0787: }
0788:
0789: private PortalApplication unmarshalPortalApplication(InputStream is)
0790: throws JAXBException, UnsupportedEncodingException {
0791:
0792: // create an Unmarshaller
0793: Unmarshaller u = this .pisfiJAXBContext.createUnmarshaller();
0794:
0795: PortalApplication app = (PortalApplication) u
0796: .unmarshal(new InputStreamReader(is, pisfiCharSet));
0797:
0798: return app;
0799:
0800: }
0801:
0802: public String[] getChildPsites(String appPath) {
0803: String path = computeAbsoluteAppFilePath(appPath);
0804: File f = new File(path);
0805: File parentDir = f.getParentFile().getParentFile();
0806: File[] children = parentDir.listFiles();
0807: if (children == null || children.length == 0)
0808: return null;
0809: Vector<String> vec = new Vector<String>();
0810: String psiteDataDir = PSITE_DATA_DIR.substring(1);
0811: for (int i = 0; i < children.length; i++) {
0812: String childName = children[i].getName();
0813: if (children[i].isDirectory()
0814: && !(childName.equals(psiteDataDir))
0815: && !childName.startsWith("."))
0816: vec.add(children[i].getName());
0817: }
0818: String[] retVal = new String[vec.size()];
0819: vec.copyInto(retVal);
0820: return retVal;
0821:
0822: }
0823:
0824: public String getPortalApplicationOwner(String appPath) {
0825: try {
0826: return readOwner(appPath);
0827: } catch (IOException ex) {
0828: return null;
0829: }
0830: }
0831:
0832: private String getCurrentLock(String appPath) throws IOException {
0833: String absIndexFilePath = computeAbsoluteAppFilePath(appPath);
0834: File indexFile = new File(absIndexFilePath);
0835: if (!indexFile.exists())
0836: throw new IOException("Nonexistent application.");
0837: File lockFile = new File(indexFile.getParentFile(), LOCK_FILE);
0838: if (!lockFile.exists())
0839: return null;
0840: else
0841: return IOUtil.getFileContentAsString(lockFile);
0842:
0843: }
0844:
0845: private void writeLock(String appPath, String user)
0846: throws IOException {
0847: String absIndexFilePath = computeAbsoluteAppFilePath(appPath);
0848: File indexFile = new File(absIndexFilePath);
0849: File lockFile = new File(indexFile.getParentFile(), LOCK_FILE);
0850: IOUtil.createFile(lockFile.getAbsolutePath(), user, "utf-8");
0851: }
0852:
0853: private void removeLock(String appPath) throws IOException {
0854: String absIndexFilePath = computeAbsoluteAppFilePath(appPath);
0855: File indexFile = new File(absIndexFilePath);
0856: File lockFile = new File(indexFile.getParentFile(), LOCK_FILE);
0857: lockFile.delete();
0858: }
0859:
0860: private void writeMembers(String appPath, String[] members)
0861: throws IOException {
0862: String absIndexFilePath = computeAbsoluteAppFilePath(appPath);
0863: File indexFile = new File(absIndexFilePath);
0864: File memberFile = new File(indexFile.getParentFile(),
0865: MEMBER_FILE);
0866: FileWriter w = null;
0867: try {
0868: w = new FileWriter(memberFile);
0869: w.write(members[0]);
0870: for (int i = 1; i < members.length; i++) {
0871: w.write("\n");
0872: w.write(members[i]);
0873: }
0874: w.flush();
0875: } finally {
0876: if (w != null)
0877: w.close();
0878: }
0879: }
0880:
0881: private void removeMembers(String appPath) throws IOException {
0882: String absIndexFilePath = computeAbsoluteAppFilePath(appPath);
0883: File indexFile = new File(absIndexFilePath);
0884: File lockFile = new File(indexFile.getParentFile(), MEMBER_FILE);
0885: lockFile.delete();
0886: uncacheMembers(appPath);
0887: }
0888:
0889: private String[] readMembers(String appPath) throws IOException {
0890:
0891: String absIndexFilePath = computeAbsoluteAppFilePath(appPath);
0892: File indexFile = new File(absIndexFilePath);
0893: File memberFile = new File(indexFile.getParentFile(),
0894: MEMBER_FILE);
0895: if (memberFile.exists()) {
0896: LineNumberReader r = null;
0897: Vector<String> memberVec = new Vector<String>();
0898: try {
0899: r = new LineNumberReader(new FileReader(memberFile));
0900: String member = r.readLine();
0901: while (member != null) {
0902: memberVec.add(member);
0903: member = r.readLine();
0904: }
0905: String[] memberArray = new String[memberVec.size()];
0906: memberVec.copyInto(memberArray);
0907: cacheMembers(appPath, memberArray);
0908: return memberArray;
0909: } finally {
0910: if (r != null)
0911: r.close();
0912: }
0913: } else {
0914: return null;
0915: }
0916: }
0917:
0918: private String[] getOwnedApps(String userName) throws IOException {
0919: Vector<String> ownedAppsVec = new Vector<String>();
0920: addOwnedApps(userName, "", ownedAppsVec);
0921: String[] ownedApps = new String[ownedAppsVec.size()];
0922: ownedAppsVec.copyInto(ownedApps);
0923: return ownedApps;
0924: }
0925:
0926: private void addOwnedApps(String userName, String appPath,
0927: Vector<String> appVec) throws IOException {
0928: if (appPath.equals("/my"))
0929: return;
0930: String appOwner = readOwner(appPath);
0931: if (appOwner.equals(userName)) {
0932: appVec.addElement(appPath);
0933: }
0934: String[] children = getChildPsites(appPath);
0935: if (children != null) {
0936: for (int i = 0; i < children.length; i++) {
0937: addOwnedApps(userName, appPath + "/" + children[i],
0938: appVec);
0939: }
0940: }
0941: }
0942:
0943: private String readOwner(String appPath) throws IOException {
0944:
0945: String absIndexFilePath = computeAbsoluteAppFilePath(appPath);
0946: File indexFile = new File(absIndexFilePath);
0947: File ownerFile = new File(indexFile.getParentFile(), OWNER_FILE);
0948: if (ownerFile.exists()) {
0949: return IOUtil.getFileContentAsString(ownerFile);
0950: } else {
0951: return DEFAULT_OWNER;
0952: }
0953: }
0954:
0955: private void writeOwner(String appPath, String owner)
0956: throws IOException {
0957: String absIndexFilePath = computeAbsoluteAppFilePath(appPath);
0958: File indexFile = new File(absIndexFilePath);
0959: File memberFile = new File(indexFile.getParentFile(),
0960: OWNER_FILE);
0961: FileWriter w = null;
0962: try {
0963: w = new FileWriter(memberFile);
0964: w.write(owner);
0965: w.flush();
0966: } finally {
0967: if (w != null)
0968: w.close();
0969: }
0970: }
0971:
0972: private PortalApplication getCachedApp(String path) {
0973: return this .pisfiPortalAppMap.get(path);
0974: }
0975:
0976: private void cacheMembers(String appPath, String[] members) {
0977: this .pisfiMembersMap.put(appPath, members);
0978: }
0979:
0980: private void uncacheMembers(String appPath) {
0981: this .pisfiMembersMap.remove(appPath);
0982: }
0983:
0984: private String[] getMembersFromCache(String appPath) {
0985: return this .pisfiMembersMap.get(appPath);
0986: }
0987:
0988: private void cacheAppPaths(String owner, String[] appPaths) {
0989: this .pisfiOwnerAppPathMap.put(owner, appPaths);
0990: }
0991:
0992: private void uncacheAppPaths(String owner) {
0993: this .pisfiOwnerAppPathMap.remove(owner);
0994: }
0995:
0996: private String[] getAppPathsFromCache(String userName) {
0997: return this .pisfiOwnerAppPathMap.get(userName);
0998: }
0999:
1000: private void cacheApp(PortalApplication app) {
1001: app.setStale(false);
1002: this .pisfiPortalAppMap.put(app.getPath(), app);
1003: }
1004:
1005: private void uncacheApp(String appPath) {
1006: PortalApplication app = this .pisfiPortalAppMap.remove(appPath);
1007: if (app != null)
1008: app.setStale(true);
1009: }
1010:
1011: public String restorePortletConfiguration() throws RemoteException {
1012: InputStream fis = null;
1013: String realPath = soiServerContext
1014: .getRealPath(PORTLET_XML_PATH);
1015: if (realPath == null) {
1016: fis = soiServerContext
1017: .getResourceAsStream(PORTLET_XML_PATH);
1018: } else {
1019: File f = new File(realPath);
1020: if (f.exists()) {
1021: try {
1022: fis = new FileInputStream(f);
1023: } catch (FileNotFoundException e) {
1024: // ignore
1025: }
1026: } else {
1027: fis = soiServerContext
1028: .getResourceAsStream(PORTLET_XML_PATH);
1029: }
1030: }
1031: if (fis == null)
1032: throw new RemoteException(
1033: "Failed to locate portlet.xml file.");
1034: try {
1035: return IOUtil.getInputStreamContentAsString(fis,
1036: pisfiCharSet);
1037: } catch (IOException e) {
1038: throw new RemoteException(
1039: "Encountered IO exception in reading portlet.xml file.",
1040: e);
1041: } finally {
1042: try {
1043: fis.close();
1044: } catch (Exception e) { /* Ignore */
1045: }
1046: }
1047: }
1048:
1049: public void savePortletConfiguration(String configXML)
1050: throws RemoteException {
1051: String realPath = soiServerContext
1052: .getRealPath(PORTLET_XML_PATH);
1053: if (realPath == null) {
1054: throw new RemoteException(
1055: "Could not find real path of portlet.xml file. Are you deploying Stringbeans in unexploded war file?");
1056: }
1057: File f = new File(realPath);
1058: try {
1059: IOUtil.saveAndBackupFile(f, configXML, pisfiCharSet);
1060: } catch (IOException e) {
1061: throw new RemoteException(
1062: "Failed to save portlet.xml file.", e);
1063: }
1064:
1065: }
1066:
1067: public UserPreferences getUserPreferences(String name)
1068: throws RemoteException {
1069: File f = new File(pisfiUserPrefsDirAbsPath + File.separator
1070: + name, name + ".xml");
1071: InputStream is = null;
1072: if (!f.exists()) {
1073: // Try getting the resource at relative directory path
1074: is = soiServerContext
1075: .getResourceAsStream(pisfiPortalAppDir);
1076: } else {
1077: try {
1078: is = new FileInputStream(f);
1079: } catch (FileNotFoundException e) {
1080: // Will never happen since we are checking if the file exists.
1081: }
1082: }
1083:
1084: if (is == null)
1085: return null;
1086:
1087: try {
1088: // create an Unmarshaller
1089: Unmarshaller u = this .pisfiJAXBContext.createUnmarshaller();
1090:
1091: return (UserPreferences) u.unmarshal(new InputStreamReader(
1092: is, pisfiCharSet));
1093: } catch (JAXBException e) {
1094: throw new RemoteException(
1095: "Failed to unmarshal portal application.", e);
1096: } catch (UnsupportedEncodingException e) {
1097: throw new RemoteException(
1098: "Failed to unmarshal portal application.", e);
1099: } finally {
1100: try {
1101: if (is != null)
1102: is.close();
1103: } catch (Exception e) {
1104: }
1105: }
1106:
1107: }
1108:
1109: public void saveUserPreferences(UserPreferences prefs)
1110: throws RemoteException {
1111: File f = null;
1112: String userName = prefs.getName();
1113:
1114: f = getUserPreferenceFile(userName);
1115:
1116: if (f.exists() && !f.canWrite()) {
1117: throw new RemoteException(
1118: "User preferences file is not writable.");
1119: }
1120:
1121: OutputStreamWriter w = null;
1122: try {
1123: w = new OutputStreamWriter(new FileOutputStream(f),
1124: pisfiCharSet);
1125: Marshaller m = this .pisfiJAXBContext.createMarshaller();
1126: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
1127: m.marshal(prefs, w);
1128: w.flush();
1129: } catch (FileNotFoundException e) {
1130: throw new RemoteException("Invalid user name: " + userName,
1131: e);
1132: } catch (IOException e) {
1133: throw new RemoteException(
1134: "Failed to save user preference file.", e);
1135: } catch (JAXBException e) {
1136: throw new RemoteException(
1137: "Failed to unmarshal portal application.", e);
1138: } finally {
1139: try {
1140: if (w != null)
1141: w.close();
1142: } catch (Exception e) {
1143: }
1144: }
1145:
1146: }
1147:
1148: public PortalConfiguration restorePortalConfiguration()
1149: throws RemoteException {
1150: InputStream fis = null;
1151: String realPath = soiServerContext.getRealPath(PORTAL_XML_PATH);
1152: if (realPath == null) {
1153: fis = soiServerContext.getResourceAsStream(PORTAL_XML_PATH);
1154: } else {
1155: File f = new File(realPath);
1156: if (f.exists()) {
1157: try {
1158: fis = new FileInputStream(f);
1159: } catch (FileNotFoundException e) {
1160: // ignore
1161: }
1162: } else {
1163: fis = soiServerContext
1164: .getResourceAsStream(PORTAL_XML_PATH);
1165: }
1166: }
1167: if (fis == null)
1168: throw new RemoteException(
1169: "Failed to locate portal.xml file.");
1170: try {
1171:
1172: // create an Unmarshaller
1173: Unmarshaller u = this .pisfiJAXBContext.createUnmarshaller();
1174:
1175: return (PortalConfiguration) u
1176: .unmarshal(new InputStreamReader(fis, pisfiCharSet));
1177:
1178: } catch (IOException e) {
1179: throw new RemoteException(
1180: "Encountered IO exception in reading portal.xml file.",
1181: e);
1182: } catch (JAXBException e) {
1183: throw new RemoteException(
1184: "Failed to unmarshal portal configuration.", e);
1185: } finally {
1186: try {
1187: fis.close();
1188: } catch (Exception e) { /* Ignore */
1189: }
1190: }
1191: }
1192:
1193: public void savePortalConfiguration(PortalConfiguration pConfig)
1194: throws RemoteException {
1195: String realPath = soiServerContext.getRealPath(PORTAL_XML_PATH);
1196: if (realPath == null) {
1197: throw new RemoteException(
1198: "Could not find real path of portal.xml file. Are you deploying Stringbeans in unexploded war file?");
1199: }
1200: File f = new File(realPath);
1201:
1202: StringWriter w = null;
1203: try {
1204: w = new StringWriter();
1205: Marshaller m = this .pisfiJAXBContext.createMarshaller();
1206: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
1207: m.marshal(pConfig, w);
1208: w.flush();
1209: } catch (JAXBException e) {
1210: throw new RemoteException(
1211: "Failed to unmarshal portal application.", e);
1212: }
1213:
1214: try {
1215: IOUtil.saveAndBackupFile(f, w.toString(), pisfiCharSet);
1216: } catch (IOException e) {
1217: throw new RemoteException(
1218: "Failed to save portal.xml file.", e);
1219: }
1220:
1221: }
1222:
1223: private String computeRelativeAppFilePath(String appPath) {
1224: return this .pisfiPortalAppDir + appPath + "/index.xml";
1225:
1226: }
1227:
1228: private String computeAbsoluteAppFilePath(String appPath) {
1229: return this .pisfiPortalAppDirAbsPath + appPath + PSITE_DATA_DIR
1230: + "/index.xml";
1231:
1232: }
1233:
1234: private InputStream getPortalAppInputStream(String path) {
1235: String appFilePath = computeAbsoluteAppFilePath(path);
1236: File f = new File(appFilePath);
1237: InputStream is = null;
1238: if (!f.exists()) {
1239: // Try getting the resource at relative directory path
1240: is = soiServerContext
1241: .getResourceAsStream(computeRelativeAppFilePath(path));
1242: } else {
1243: try {
1244: is = new FileInputStream(f);
1245: } catch (FileNotFoundException e) {
1246: // Will never happen since we are checking if the file exists.
1247: }
1248: }
1249:
1250: return is;
1251:
1252: }
1253:
1254: public void deleteUserPreferences(String userName)
1255: throws RemoteException {
1256: if (userName == null || userName.equals(""))
1257: return;
1258: File f = new File(this .getUserPreferenceFilePath(userName));
1259: if (f.exists()) {
1260: IOUtil.deleteDirectory(f);
1261: }
1262: }
1263:
1264: public byte[] getUserIcon(String userName) throws RemoteException {
1265: try {
1266: File avatarFile = new File(getAvatarFilePath(userName));
1267: if (avatarFile.exists())
1268: return IOUtil.getFileContentAsBytes(avatarFile);
1269: else
1270: return null;
1271: } catch (IOException e) {
1272: throw new RemoteException(
1273: "Failed to retrieve user avatar.", e);
1274: }
1275:
1276: }
1277:
1278: public void setUserIcon(String userName, byte[] icon)
1279: throws RemoteException {
1280: try {
1281: String iconFile = getAvatarFilePath(userName);
1282: ImageUtil.createJPEGThumbnail(icon, iconFile, 120, 120);
1283: } catch (Exception e) {
1284: throw new RemoteException(
1285: "Could not create JPEG thumbnail.", e);
1286: }
1287:
1288: }
1289:
1290: private String getUserPreferenceFilePath(String userName) {
1291: return pisfiUserPrefsDirAbsPath + File.separator + userName;
1292: }
1293:
1294: private File getUserPreferenceFile(String userName)
1295: throws RemoteException {
1296: // try create parent folder
1297: File f = new File(this .getUserPreferenceFilePath(userName));
1298:
1299: if (!f.exists()) {
1300: if (!f.mkdirs())
1301: throw new RemoteException(
1302: "Failed to create root directory for storing user preferences.");
1303: }
1304:
1305: f = new File(f, userName + ".xml");
1306: return f;
1307: }
1308:
1309: private String getAvatarFilePath(String userName) {
1310: String userFilePath = this .getUserPreferenceFilePath(userName);
1311: new File(userFilePath).mkdir();
1312: return userFilePath + File.separator + "avatar.jpg";
1313: }
1314:
1315: public synchronized List<VersionInfo> getVersionHistory(
1316: String portalPath, int maxHistFiles) throws RemoteException {
1317: String path = computeAbsoluteAppFilePath(portalPath);
1318: File f = new File(path);
1319: File versionDir = new File(f.getParentFile(), VERSION_DIR);
1320: if (!versionDir.exists())
1321: return null;
1322: File[] versionedFiles = versionDir.listFiles();
1323: List<VersionInfo> vInfoList = null;
1324: FileInputStream fis = null;
1325: try {
1326: if (maxHistFiles == -1) { // return all versions
1327: vInfoList = new ArrayList<VersionInfo>(
1328: versionedFiles.length);
1329: for (int i = 0; i < versionedFiles.length; i++) {
1330: if (!versionedFiles[i].getName().startsWith(
1331: VERSION_FILE_PREFIX))
1332: continue;
1333: fis = new FileInputStream(versionedFiles[i]);
1334: PortalApplication portalApp = unmarshalPortalApplication(fis);
1335: vInfoList.add(portalApp.getVersionInfo());
1336: // sort will sort based on the creation time.
1337: Collections.sort(vInfoList);
1338: }
1339: } else {
1340: vInfoList = new ArrayList<VersionInfo>(maxHistFiles);
1341: // Need a sorted map.
1342: Map<Integer, File> versionMap = new TreeMap<Integer, File>();
1343: String fName = null;
1344: for (int i = 0; i < versionedFiles.length; i++) {
1345: fName = versionedFiles[i].getName();
1346: if (!fName.startsWith(VERSION_FILE_PREFIX))
1347: continue;
1348: versionMap.put(new Integer(fName.substring(
1349: VERSION_FILE_PREFIX.length(), fName
1350: .length() - 4)), versionedFiles[i]);
1351: }
1352:
1353: Collection<File> reqFiles = versionMap.values();
1354: Object[] obj = reqFiles.toArray();
1355: int numOfFiles = reqFiles.size();
1356: int i = 0;
1357: if (numOfFiles > maxHistFiles)
1358: i = numOfFiles - maxHistFiles;
1359:
1360: for (; i < numOfFiles; i++) {
1361: fis = new FileInputStream((File) obj[i]);
1362: PortalApplication portalApp = unmarshalPortalApplication(fis);
1363: vInfoList.add(portalApp.getVersionInfo());
1364: }
1365: }
1366: // add index.xml
1367: vInfoList.add(retrievePortalApplication(portalPath, false)
1368: .getVersionInfo());
1369:
1370: } catch (FileNotFoundException e) {
1371: throw new RemoteException(
1372: "Failed to unmarshal portal application.", e);
1373: } catch (JAXBException e) {
1374: throw new RemoteException(
1375: "Failed to unmarshal portal application.", e);
1376: } catch (UnsupportedEncodingException e) {
1377: throw new RemoteException(
1378: "Failed to unmarshal portal application.", e);
1379: } finally {
1380: try {
1381: fis.close();
1382: } catch (Exception e) { /* Ignore */
1383: }
1384: }
1385: return vInfoList;
1386:
1387: }
1388: /*
1389: public int getLastVersionNumber (String portalPath) throws RemoteException {
1390: String path = computeAbsoluteAppFilePath(portalPath);
1391: File f = new File(path);
1392: File versionDir = new File(f.getParentFile(), VERSION_DIR);
1393: if (! versionDir.exists()) return 0;
1394: String[] versionedFiles = versionDir.list(new FilenameFilter(){
1395: public boolean accept(File dir, String name) {
1396: return (name.startsWith(VERSION_FILE_PREFIX));
1397: }
1398: });
1399:
1400: if (versionedFiles.length == 0) return 0;
1401: int maxVersion = 0;
1402: for (int i=0; i<versionedFiles.length; i++) {
1403: String[] curFileTokens = StringUtil.split(versionedFiles[i], "_.");
1404: int curVersion = Integer.parseInt(curFileTokens[1]);
1405: if (curVersion > maxVersion) maxVersion = curVersion;
1406: }
1407: return maxVersion;
1408: }
1409: */
1410: }
|