/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.db; import java.util.Arrays; import com.slamd.asn1.ASN1Boolean; import com.slamd.asn1.ASN1Element; import com.slamd.asn1.ASN1OctetString; import com.slamd.asn1.ASN1Sequence; /** * This class defines a structure for storing information about a job folder. * This includes the name of the folder, the jobs and optimizing jobs that it * contains, the parent and child folders, and the permissions associated with * it. * * * @author Neil A. Wilson */ public class JobFolder { /** * The name of the encoded element that holds the name of this job folder. */ public static final String ELEMENT_NAME = "name"; /** * The name of the encoded element that indicates whether this folder should * be visible in restricted read-only mode. */ public static final String ELEMENT_DISPLAY_IN_READ_ONLY = "display_in_read_only"; /** * The name of the encoded element that indicates whether this is a virtual * folder. */ public static final String ELEMENT_IS_VIRTUAL = "is_virtual"; /** * The name of the encoded element that holds the name of the parent folder. */ public static final String ELEMENT_PARENT = "parent"; /** * The name of the encoded element that holds the names of the child folders. */ public static final String ELEMENT_CHILDREN = "children"; /** * The name of the encoded element that holds the description for this folder. */ public static final String ELEMENT_DESCRIPTION = "description"; /** * The name of the encoded element that holds the job IDs. */ public static final String ELEMENT_JOB_IDS = "jobs"; /** * The name of the encoded element that holds the optimizing job IDs. */ public static final String ELEMENT_OPTIMIZING_JOB_IDS = "optimizing_jobs"; /** * The name of the encoded element that holds the names of the uploaded files. */ public static final String ELEMENT_FILE_NAMES = "files"; /** * The name of the encoded element that holds the permissions. */ public static final String ELEMENT_PERMISSIONS = "permissions"; // Indicates whether this folder should be displayed in restricted read-only // mode. boolean displayInReadOnly; // Indicates whether this is a virtual job folder. boolean isVirtual; // The set of permissions associated with this job folder. SLAMDPermission[] permissions; // The description for this job folder. String description; // The name of this job folder. String folderName; // The name of the owner of this job folder. String ownerName; // The name of the parent folder. String parentName; // The names of all the child folders below this folder. String[] childNames; // The names of the uploaded files associated with this folder. String[] fileNames; // The job IDs of the jobs stored in this folder. String[] jobIDs; // The optimizing job IDs of the optimizing jobs stored in this folder. String[] optimizingJobIDs; /** * Creates a new job folder with the provided information. * * @param folderName The name of this job folder. * @param displayInReadOnly Indicates whether the contents of the folder * should be displayed in restricted read-only * mode. * @param isVirtual Indicates whether this is a virtual job folder. * @param parentName The name of the folder that is the parent of * this job folder. * @param childNames The names of the folders that are children of * this job folder. * @param description The description for this job folder. * @param jobIDs The job IDs of the jobs stored in this folder. * @param optimizingJobIDs The job IDs of the optimizing jobs stored in * this folder. * @param fileNames The names of the uploaded files associated with * this folder. * @param permissions The set of permissions that have been granted * for this folder. */ public JobFolder(String folderName, boolean displayInReadOnly, boolean isVirtual, String parentName, String[] childNames, String description, String[] jobIDs, String[] optimizingJobIDs, String[] fileNames, SLAMDPermission[] permissions) { this.folderName = folderName; this.displayInReadOnly = displayInReadOnly; this.isVirtual = isVirtual; this.parentName = parentName; this.description = description; if (childNames == null) { this.childNames = new String[0]; } else { this.childNames = childNames; } if (jobIDs == null) { this.jobIDs = new String[0]; } else { this.jobIDs = jobIDs; } if (optimizingJobIDs == null) { this.optimizingJobIDs = new String[0]; } else { this.optimizingJobIDs = optimizingJobIDs; } if (fileNames == null) { this.fileNames = new String[0]; } else { this.fileNames = fileNames; } if (permissions == null) { this.permissions = new SLAMDPermission[0]; } else { this.permissions = permissions; } } /** * Retrieves the name of this job folder. * * @return The name of this job folder. */ public String getFolderName() { return folderName; } /** * Indicates whether this folder should be visible in restricted read-only * mode. * * @return <CODE>true</CODE> if this folder should be visible in restricted * read-only mode, or <CODE>false</CODE> if not. */ public boolean displayInReadOnlyMode() { return displayInReadOnly; } /** * Specifies whether this folder should be visible in restricted read-only * mode. * * @param displayInReadOnly Indicates whether this folder should be visible * in restricted read-only mode. */ public void setDisplayInReadOnlyMode(boolean displayInReadOnly) { this.displayInReadOnly = displayInReadOnly; } /** * Indicates whether this is a virtual job folder. * * @return <CODE>true</CODE> if this is a virtual job folder, or * <CODE>false</CODE> if it is a real job folder. */ public boolean isVirtual() { return isVirtual; } /** * Retrieves the name of the job folder that is the parent of this job folder. * * @return The name of the parent job folder, or <CODE>null</CODE> if it is a * top-level folder. */ public String getParentName() { return parentName; } /** * Retrieves the names of the job folders that are children of this folder. * * @return The names of the job folders that are children of this folder. */ public String[] getChildNames() { return childNames; } /** * Indicates whether this job folder contains a child folder with the * specified name. * * @param childName The name of the child folder for which to make the * determination. * * @return <CODE>true</CODE> if this job folder contains a child folder with * the specified name, or <CODE>false</CODE> if not. */ public boolean containsChildName(String childName) { if (childNames == null) { return false; } for (int i=0; i < childNames.length; i++) { if (childNames[i].equals(childName)) { return true; } } return false; } /** * Specifies the names of the job folders that are children of this folder. * * @param childNames The names of the job folders that are children of this * folder. */ public void setChildNames(String[] childNames) { if (childNames == null) { childNames = new String[0]; } Arrays.sort(childNames); this.childNames = childNames; } /** * Adds the specified folder as a child of this folder. * * @param childName The name of the job folder to add as a child of this * folder. */ public void addChildName(String childName) { String[] newChildNames = new String[childNames.length+1]; for (int i=0; i < childNames.length; i++) { if (childNames[i].equals(childName)) { return; } else { newChildNames[i] = childNames[i]; } } newChildNames[childNames.length] = childName; Arrays.sort(newChildNames); childNames = newChildNames; } /** * Removes the specified folder as a child of this folder. * * @param childName The name of the job folder to remove from the set of * children for this folder. */ public void removeChildName(String childName) { int pos = -1; for (int i=0; i < childNames.length; i++) { if (childNames[i].equals(childName)) { pos = i; break; } } if (pos == -1) { return; } String[] newChildNames = new String[childNames.length-1]; System.arraycopy(childNames, 0, newChildNames, 0, pos); System.arraycopy(childNames, pos+1, newChildNames, pos, (newChildNames.length - pos)); childNames = newChildNames; } /** * Retrieves the description for this job folder. * * @return The description for this job folder. */ public String getDescription() { return description; } /** * Specifies the description for this job folder. * * @param description The description for this job folder. */ public void setDescription(String description) { this.description = description; } /** * Retrieves the job IDs of all jobs associated with this folder. * * @return The job IDs of all jobs associated with this folder. */ public String[] getJobIDs() { return jobIDs; } /** * Indicates whether this job folder contains a job with the specified ID. * * @param jobID The job ID for which to make the determination. * * @return <CODE>true</CODE> if this job folder contains a job with the * specified job ID, or <CODE>false</CODE> if not. */ public boolean containsJobID(String jobID) { if (jobIDs == null) { return false; } for (int i=0; i < jobIDs.length; i++) { if (jobIDs[i].equals(jobID)) { return true; } } return false; } /** * Specifies the job IDs of all jobs associated with this folder. * * @param jobIDs The job IDs of all jobs associated with this folder. */ public void setJobIDs(String[] jobIDs) { if (jobIDs == null) { jobIDs = new String[0]; } Arrays.sort(jobIDs); this.jobIDs = jobIDs; } /** * Adds the provided job ID to the set of jobs associated with this folder. * * @param jobID The job ID to add to the set of jobs associated with this * folder. */ public void addJobID(String jobID) { String[] newIDs = new String[jobIDs.length+1]; for (int i=0; i < jobIDs.length; i++) { if (jobIDs[i].equals(jobID)) { return; } else { newIDs[i] = jobIDs[i]; } } newIDs[jobIDs.length] = jobID; Arrays.sort(newIDs); jobIDs = newIDs; } /** * Removes the provided job ID from the set of jobs associated with this * folder. * * @param jobID The job ID to remove from the set of jobs associated with * this folder. */ public void removeJobID(String jobID) { int pos = -1; for (int i=0; i < jobIDs.length; i++) { if (jobIDs[i].equals(jobID)) { pos = i; break; } } if (pos == -1) { return; } String[] newJobIDs = new String[jobIDs.length-1]; System.arraycopy(jobIDs, 0, newJobIDs, 0, pos); System.arraycopy(jobIDs, pos+1, newJobIDs, pos, (newJobIDs.length - pos)); jobIDs = newJobIDs; } /** * Retrieves the optimizing job IDs of all optimizing jobs associated with * this folder. * * @return The optimizing job IDs of all optimizing jobs associated with this * folder. */ public String[] getOptimizingJobIDs() { return optimizingJobIDs; } /** * Indicates whether this job folder contains an optimizing job with the * specified ID. * * @param optimizingJobID The optimizing job ID for which to make the * determination. * * @return <CODE>true</CODE> if this job folder contains an optimizing job * with the specified ID, or <CODE>false</CODE> if not. */ public boolean containsOptimizingJobID(String optimizingJobID) { if (optimizingJobIDs == null) { return false; } for (int i=0; i < optimizingJobIDs.length; i++) { if (optimizingJobIDs[i].equals(optimizingJobID)) { return true; } } return false; } /** * Specifies the optimizing job IDs of all optimizing jobs associated with * this folder. * * @param optimizingJobIDs The optimizing job IDs of all optimizing jobs * associated with this folder. */ public void setOptimzizingJobIDs(String[] optimizingJobIDs) { if (optimizingJobIDs == null) { optimizingJobIDs = new String[0]; } Arrays.sort(optimizingJobIDs); this.optimizingJobIDs = optimizingJobIDs; } /** * Adds the provided optimizing job ID to the set of optimizing jobs * associated with this folder. * * @param optimizingJobID The optimizing job ID to add to the set of * optimizing jobs associated with this folder. */ public void addOptimizingJobID(String optimizingJobID) { String[] newIDs = new String[optimizingJobIDs.length+1]; for (int i=0; i < optimizingJobIDs.length; i++) { if (optimizingJobIDs[i].equals(optimizingJobID)) { return; } else { newIDs[i] = optimizingJobIDs[i]; } } newIDs[optimizingJobIDs.length] = optimizingJobID; Arrays.sort(newIDs); optimizingJobIDs = newIDs; } /** * Removes the provided optimizing job ID from the set of optimizing jobs * associated with this folder. * * @param optimizingJobID The optimizing job ID to remove from the set of * optimizing jobs associated with this folder. */ public void removeOptimizingJobID(String optimizingJobID) { int pos = -1; for (int i=0; i < optimizingJobIDs.length; i++) { if (optimizingJobIDs[i].equals(optimizingJobID)) { pos = i; break; } } if (pos == -1) { return; } String[] newOptimizingIDs = new String[optimizingJobIDs.length-1]; System.arraycopy(optimizingJobIDs, 0, newOptimizingIDs, 0, pos); System.arraycopy(optimizingJobIDs, pos+1, newOptimizingIDs, pos, (newOptimizingIDs.length - pos)); optimizingJobIDs = newOptimizingIDs; } /** * Retrieves the names of the uploaded files associated with this job folder. * * @return The names of the uploaded files associated with this job folder. */ public String[] getFileNames() { return fileNames; } /** * Indicates whether this job folder contains an uploaded file with the * specified name. * * @param fileName The file name for which to make the determination. * * @return <CODE>true</CODE> if this job folder contains an uploaded file * with the specified name, or <CODE>false</CODE> if it does not. */ public boolean containsFileName(String fileName) { if (fileNames == null) { return false; } for (int i=0; i < fileNames.length; i++) { if (fileNames[i].equals(fileName)) { return true; } } return false; } /** * Specifies the names of the uploaded files associated with this job folder. * * @param fileNames The names of the uploaded files associated with this job * folder. */ public void setFileNames(String[] fileNames) { if (fileNames == null) { fileNames = new String[0]; } this.fileNames = fileNames; } /** * Adds the specified file name to the set of uploaded files for this job * folder. * * @param fileName The name of the file to add to the uploaded files for * this job folder. */ public void addFileName(String fileName) { String[] newFiles = new String[fileNames.length+1]; for (int i=0; i < fileNames.length; i++) { if (fileNames[i].equals(fileName)) { return; } else { newFiles[i] = fileNames[i]; } } newFiles[fileNames.length] = fileName; Arrays.sort(newFiles); fileNames = newFiles; } /** * Removes the specified file name from the set of uploaded files for this job * folder. * * @param fileName The name of the file to remove from the set of uploaded * files for this job folder. */ public void removeFileName(String fileName) { int pos = -1; for (int i=0; i < fileNames.length; i++) { if (fileNames[i].equals(fileName)) { pos = i; break; } } if (pos == -1) { return; } String[] newFileNames = new String[fileNames.length-1]; System.arraycopy(fileNames, 0, newFileNames, 0, pos); System.arraycopy(fileNames, pos+1, newFileNames, pos, (newFileNames.length - pos)); fileNames = newFileNames; } /** * Retrieves the set of permissions associated with this job folder. * * @return The set of permissions associated with this job folder. */ public SLAMDPermission[] getPermissions() { return permissions; } /** * Determines whether the provided user has the specified permission for this * job folder. * * @param user The user for which to make the determination. * @param permissionName The name of the permission to check for the * provided user. * * @return <CODE>true</CODE> if the user has the specified permission or * <CODE>false</CODE> if not. */ public boolean userHasPermission(SLAMDUser user, String permissionName) { for (int i=0; i < permissions.length; i++) { if (permissions[i].getName().equals(permissionName)) { return permissions[i].appliesToUser(user); } } return false; } /** * Specifies the set of permissions to use for this folder. * * @param permissions The set of permissions to use for this folder. */ public void setPermissions(SLAMDPermission[] permissions) { if (permissions == null) { permissions = new SLAMDPermission[0]; } this.permissions = permissions; } /** * Sets the provided permission for this group. If a permission already * exists with the provided name, then it will be replaced, otherwise it will * be added. * * @param permission The permission to set for this folder. */ public void setPermission(SLAMDPermission permission) { for (int i=0; i < permissions.length; i++) { if (permissions[i].getName().equals(permission.getName())) { permissions[i] = permission; return; } } SLAMDPermission[] newPermissions = new SLAMDPermission[permissions.length+1]; System.arraycopy(permissions, 0, newPermissions, 0, permissions.length); newPermissions[permissions.length] = permission; permissions = newPermissions; } /** * Removes the permission with the specified name from this job folder. * * @param permissionName The name of the permission to remove from this * folder. */ public void removePermission(String permissionName) { int pos = -1; for (int i=0; i < permissions.length; i++) { if (permissions[i].getName().equals(permissionName)) { pos = i; break; } } if (pos == -1) { return; } SLAMDPermission[] newPermissions = new SLAMDPermission[permissions.length-1]; System.arraycopy(permissions, 0, newPermissions, 0, pos); System.arraycopy(permissions, pos+1, newPermissions, pos, (newPermissions.length - pos)); permissions = newPermissions; } /** * Encodes the information in this job folder to a byte array. * * @return The byte array containing the encoded job folder. */ public byte[] encode() { ASN1Element[] childElements = new ASN1Element[childNames.length]; for (int i=0; i < childNames.length; i++) { childElements[i] = new ASN1OctetString(childNames[i]); } ASN1Element[] jobElements = new ASN1Element[jobIDs.length]; for (int i=0; i < jobIDs.length; i++) { jobElements[i] = new ASN1OctetString(jobIDs[i]); } ASN1Element[] optimizingElements = new ASN1Element[optimizingJobIDs.length]; for (int i=0; i < optimizingJobIDs.length; i++) { optimizingElements[i] = new ASN1OctetString(optimizingJobIDs[i]); } ASN1Element[] fileElements = new ASN1Element[fileNames.length]; for (int i=0; i < fileNames.length; i++) { fileElements[i] = new ASN1OctetString(fileNames[i]); } ASN1Element[] permissionElements = new ASN1Element[permissions.length]; for (int i=0; i < permissions.length; i++) { permissionElements[i] = permissions[i].encodeAsSequence(); } ASN1Element[] folderElements = new ASN1Element[] { new ASN1OctetString(ELEMENT_NAME), new ASN1OctetString(folderName), new ASN1OctetString(ELEMENT_DISPLAY_IN_READ_ONLY), new ASN1Boolean(displayInReadOnly), new ASN1OctetString(ELEMENT_IS_VIRTUAL), new ASN1Boolean(isVirtual), new ASN1OctetString(ELEMENT_PARENT), new ASN1OctetString(parentName), new ASN1OctetString(ELEMENT_CHILDREN), new ASN1Sequence(childElements), new ASN1OctetString(ELEMENT_DESCRIPTION), new ASN1OctetString(description), new ASN1OctetString(ELEMENT_JOB_IDS), new ASN1Sequence(jobElements), new ASN1OctetString(ELEMENT_OPTIMIZING_JOB_IDS), new ASN1Sequence(optimizingElements), new ASN1OctetString(ELEMENT_FILE_NAMES), new ASN1Sequence(fileElements), new ASN1OctetString(ELEMENT_PERMISSIONS), new ASN1Sequence(permissionElements) }; return new ASN1Sequence(folderElements).encode(); } /** * Decodes the provided byte array as a job folder. * * @param encodedFolder The byte array containing the encoded folder data. * * @return The decoded job folder. * * @throws DecodeException If a problem occurs while attempting to decode * the job folder. */ public static JobFolder decode(byte[] encodedFolder) throws DecodeException { try { boolean displayInReadOnly = false; boolean isVirtual = false; SLAMDPermission[] permissions = new SLAMDPermission[0]; String description = null; String folderName = null; String parentName = null; String[] childNames = new String[0]; String[] fileNames = new String[0]; String[] jobIDs = new String[0]; String[] optimizingJobIDs = new String[0]; ASN1Element element = ASN1Element.decode(encodedFolder); ASN1Element[] elements = element.decodeAsSequence().getElements(); for (int i=0; i < elements.length; i += 2) { String elementName = elements[i].decodeAsOctetString().getStringValue(); if (elementName.equals(ELEMENT_NAME)) { folderName = elements[i+1].decodeAsOctetString().getStringValue(); } else if (elementName.equals(ELEMENT_DISPLAY_IN_READ_ONLY)) { displayInReadOnly = elements[i+1].decodeAsBoolean().getBooleanValue(); } else if (elementName.equals(ELEMENT_IS_VIRTUAL)) { isVirtual = elements[i+1].decodeAsBoolean().getBooleanValue(); } else if (elementName.equals(ELEMENT_PARENT)) { parentName = elements[i+1].decodeAsOctetString().getStringValue(); } else if (elementName.equals(ELEMENT_CHILDREN)) { ASN1Element[] childElements = elements[i+1].decodeAsSequence().getElements(); childNames = new String[childElements.length]; for (int j=0; j < childNames.length; j++) { childNames[j] = childElements[j].decodeAsOctetString().getStringValue(); } } else if (elementName.equals(ELEMENT_DESCRIPTION)) { description = elements[i+1].decodeAsOctetString().getStringValue(); } else if (elementName.equals(ELEMENT_JOB_IDS)) { ASN1Element[] jobElements = elements[i+1].decodeAsSequence().getElements(); jobIDs = new String[jobElements.length]; for (int j=0; j < jobIDs.length; j++) { jobIDs[j] = jobElements[j].decodeAsOctetString().getStringValue(); } } else if (elementName.equals(ELEMENT_OPTIMIZING_JOB_IDS)) { ASN1Element[] optimizingElements = elements[i+1].decodeAsSequence().getElements(); optimizingJobIDs = new String[optimizingElements.length]; for (int j=0; j < optimizingJobIDs.length; j++) { optimizingJobIDs[j] = optimizingElements[j].decodeAsOctetString().getStringValue(); } } else if (elementName.equals(ELEMENT_FILE_NAMES)) { ASN1Element[] fileElements = elements[i+1].decodeAsSequence().getElements(); fileNames = new String[fileElements.length]; for (int j=0; j < fileNames.length; j++) { fileNames[j] = fileElements[j].decodeAsOctetString().getStringValue(); } } else if (elementName.equals(ELEMENT_PERMISSIONS)) { ASN1Element[] permissionElements = elements[i+1].decodeAsSequence().getElements(); permissions = new SLAMDPermission[permissionElements.length]; for (int j=0; j < permissions.length; j++) { permissions[j] = SLAMDPermission.decodeSequence(permissionElements[j]. decodeAsSequence()); } } } return new JobFolder(folderName, displayInReadOnly, isVirtual, parentName, childNames, description, jobIDs, optimizingJobIDs, fileNames, permissions); } catch (Exception e) { e.printStackTrace(); throw new DecodeException("Unable to decode job folder: " + e, e); } } }