All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.drools.repository.PackageItem Maven / Gradle / Ivy

There is a newer version: 5.6.0.Final
Show newest version
/*
 * Copyright 2010 JBoss Inc
 *
 * 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.drools.repository;

import org.drools.repository.utils.NodeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.*;
import javax.jcr.nodetype.NodeType;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import java.io.InputStream;
import java.util.*;

/**
 * A PackageItem object aggregates a set of assets (for example, rules). This is
 * advantageous for systems using the JBoss Rules engine where the application
 * might make use of many related rules.
 * 

* A PackageItem refers to rule nodes within the RulesRepository. It contains * the "master copy" of assets (which may be linked into other packages or other * types of containers). This is a container "node". */ public class PackageItem extends VersionableItem { private static final Logger log = LoggerFactory.getLogger(PackageItem.class); /** * This is the name of the rules "subfolder" where rules are kept for this * package. */ public static final String ASSET_FOLDER_NAME = "assets"; /** * The dublin core format attribute. */ public static final String PACKAGE_FORMAT = "package"; /** * The name of the rule package node type */ public static final String RULE_PACKAGE_TYPE_NAME = "drools:packageNodeType"; public static final String HEADER_PROPERTY_NAME = "drools:header"; public static final String EXTERNAL_URI_PROPERTY_NAME = "drools:externalURI"; public static final String CATEGORY_RULE_KEYS_PROPERTY_NAME = "categoryRuleKeys"; public static final String CATEGORY_RULE_VALUES_PROPERTY_NAME = "categoryRuleValues"; public static final String WORKSPACE_PROPERTY_NAME = "drools:workspace"; public static final String DEPENDENCIES_PROPERTY_NAME = "drools:dependencies"; private static final String COMPILED_PACKAGE_PROPERTY_NAME = "drools:compiledPackage"; private final String BINARY_UP_TO_DATE = "drools:binaryUpToDate"; /** * Constructs an object of type RulePackageItem corresponding the specified * node * * @param rulesRepository the rulesRepository that instantiated this object * @param node the node to which this object corresponds * @throws RulesRepositoryException */ public PackageItem(RulesRepository rulesRepository, Node node) throws RulesRepositoryException { super(rulesRepository, node); try { //make sure this node is a rule package node if (!(this.node.getPrimaryNodeType().getName().equals(RULE_PACKAGE_TYPE_NAME) || isHistoricalVersion())) { String message = this.node.getName() + " is not a node of type " + RULE_PACKAGE_TYPE_NAME + ". It is a node of type: " + this.node.getPrimaryNodeType().getName(); log.error(message); throw new RulesRepositoryException(message); } } catch (Exception e) { log.error("Caught exception: " + e); throw new RulesRepositoryException(e); } } PackageItem() { super(null, null); } /** * Return the name of the package. */ public String getName() { return super.getName(); } /** * @return true if this package is actually a snapshot. */ public boolean isSnapshot() { try { return (!this.rulesRepository.isNotSnapshot(this.node.getParent())); } catch (RepositoryException e) { throw new IllegalStateException(e); } } /** * Set this to indicate if the binary is up to date, or not. */ public void updateBinaryUpToDate(boolean status) { try { checkIsUpdateable(); this.checkout(); node.setProperty(BINARY_UP_TO_DATE, status); } catch (RepositoryException e) { log.error("fail to update drools:binaryUpToDate of " + getName(), e); } } /** * Return true if the binary is "up to date". * * @return */ public boolean isBinaryUpToDate() { try { return this.node.hasProperty(BINARY_UP_TO_DATE) && node.getProperty(BINARY_UP_TO_DATE).getBoolean(); } catch (RepositoryException e) { log.error("fail to get drools:binaryUpToDate of " + getName(), e); throw new RulesRepositoryException(e); } } /** * returns the name of the snapshot, if this package is really a snapshot. * If it is not, it will just return the name of the package, so use wisely * ! */ public String getSnapshotName() { try { return this.node.getName(); } catch (RepositoryException e) { throw new RulesRepositoryException(e); } } /** * @return the workspace this package belongs to. * @throws RulesRepositoryException */ public String[] getWorkspaces() throws RulesRepositoryException { return getStringPropertyArray(WORKSPACE_PROPERTY_NAME); } /** * This sets the Workspace * * @param workspace */ public void updateWorkspace(String[] workspace) { this.updateStringArrayProperty(workspace, WORKSPACE_PROPERTY_NAME, false); } /** * This adds a workspace * * @param workspace */ public void addWorkspace(String workspace) { String[] existingWorkspaces = getStringPropertyArray(WORKSPACE_PROPERTY_NAME); boolean found = false; for (String existingWorkspace : existingWorkspaces) { if (existingWorkspace.equals(workspace)) { found = true; break; } } if (!found) { String[] newWorkspaces = new String[existingWorkspaces.length + 1]; System.arraycopy(existingWorkspaces, 0, newWorkspaces, 0, existingWorkspaces.length); newWorkspaces[existingWorkspaces.length] = workspace; this.updateStringArrayProperty(newWorkspaces, WORKSPACE_PROPERTY_NAME, false); } } /** * This removes a workspace * * @param workspace */ public void removeWorkspace(String workspace) { String[] existingWorkspaces = getStringPropertyArray(WORKSPACE_PROPERTY_NAME); if (existingWorkspaces.length == 0) { return; } List existingWorkspaceList = new ArrayList(existingWorkspaces.length); Collections.addAll(existingWorkspaceList, existingWorkspaces); existingWorkspaceList.remove(workspace); if (existingWorkspaceList.size() != existingWorkspaces.length) { this.updateStringArrayProperty(existingWorkspaceList.toArray(new String[existingWorkspaceList.size()]), WORKSPACE_PROPERTY_NAME, false); } } /** * Adds a rule to the current package with no category (not recommended !). * Without categories, its going to be hard to find rules later on (unless * packages are enough for you). */ public AssetItem addAsset(String assetName, String description) { return addAsset(assetName, description, null, null); } /** * This adds a rule to the current physical package (you can move it later). * With the given category. *

* This will NOT check the asset in, just create the basic record. * * @param assetName The name of the asset (the file name minus the extension) * @param description A description of the asset. * @param initialCategory The initial category the asset is placed in (can belong to * multiple ones later). * @param format The dublin core format (which also determines what editor is * used) - this is effectively the file extension. */ public AssetItem addAsset(String assetName, String description, String initialCategory, String format) { Node ruleNode; try { assetName = assetName.trim(); Node rulesFolder = this.node.getNode(ASSET_FOLDER_NAME); String assetPath = NodeUtils.makeJSR170ComplaintName(assetName); ruleNode = rulesFolder.addNode(assetPath, AssetItem.RULE_NODE_TYPE_NAME); ruleNode.setProperty(AssetItem.TITLE_PROPERTY_NAME, assetName); ruleNode.setProperty(AssetItem.DESCRIPTION_PROPERTY_NAME, description); if (format != null) { ruleNode.setProperty(AssetItem.FORMAT_PROPERTY_NAME, format); } else { ruleNode.setProperty(AssetItem.FORMAT_PROPERTY_NAME, AssetItem.DEFAULT_CONTENT_FORMAT); } ruleNode.setProperty(VersionableItem.CHECKIN_COMMENT, "Initial"); Calendar lastModified = Calendar.getInstance(); ruleNode.setProperty(AssetItem.LAST_MODIFIED_PROPERTY_NAME, lastModified); ruleNode.setProperty(AssetItem.PACKAGE_NAME_PROPERTY, this.getName()); ruleNode.setProperty(CREATOR_PROPERTY_NAME, this.node.getSession().getUserID()); rulesRepository.getSession().save(); AssetItem rule = new AssetItem(this.rulesRepository, ruleNode); rule.updateState(StateItem.DRAFT_STATE_NAME); if (initialCategory != null) { rule.addCategory(initialCategory); } return rule; } catch (RepositoryException e) { if (e instanceof ItemExistsException) { throw new RulesRepositoryException("A rule of that name already exists in that package.", e); } else { throw new RulesRepositoryException(e); } } } /** * This adds a rule which is imported from global area. *

* This will NOT check the asset in, just create the basic record. * * @param sharedAssetName The name of the imported asset */ public AssetItem addAssetImportedFromGlobalArea(String sharedAssetName) { try { //assetName = assetName.trim(); Node rulesFolder = this.node.getNode(ASSET_FOLDER_NAME); Session session = rulesRepository.getSession(); Workspace workspace = session.getWorkspace(); PackageItem globalArea = rulesRepository.loadGlobalArea(); AssetItem globalAssetItem = globalArea.loadAsset(sharedAssetName); ensureMixinType(globalAssetItem, "mix:shareable"); String path = rulesFolder.getPath() + "/" + globalAssetItem.getName(); workspace.clone(workspace.getName(), globalAssetItem.getNode().getPath(), path, false); Node ruleNode = rulesFolder.getNode(globalAssetItem.getName()); return new AssetItem(this.rulesRepository, ruleNode); } catch (RepositoryException e) { if (e instanceof ItemExistsException) { throw new RulesRepositoryException("A rule of that name already exists in that package.", e); } else { throw new RulesRepositoryException(e); } } } public static void ensureMixinType(AssetItem assetItem, String mixin) throws RepositoryException { if (!assetItem.getNode().isNodeType(mixin)) { assetItem.checkout(); assetItem.getNode().addMixin(mixin); assetItem.checkin("add " + mixin); } } private boolean hasMixin(Node node) { try { NodeType[] nodeTypes = node.getMixinNodeTypes(); for (NodeType nodeType : nodeTypes) { if (nodeType.isNodeType("mix:shareable")) { return true; } } } catch (RepositoryException e) { } return false; } /** * This will permanently delete this package. */ public void remove() { checkIsUpdateable(); try { log.info("USER:" + getCurrentUserName() + " REMOVEING package [" + getName() + "]"); this.node.remove(); } catch (RepositoryException e) { throw new RulesRepositoryException("Was not able to delete package.", e); } } /** * To avoid updating dependency attribute for every asset operation like * adding/renaming/deleting etc, we calculate dependency path on the fly. * * @return String[] The dependency path. */ public String[] getDependencies() { Map result = new HashMap(); try { Node content = getVersionContentNode(); Iterator assets = new AssetItemIterator(content.getNode( ASSET_FOLDER_NAME).getNodes(), this.rulesRepository); while (assets.hasNext()) { AssetItem asset = assets.next(); result.put(asset.getName(), encodeDependencyPath( asset.getName(), isHistoricalVersion() ? Long.toString(asset.getVersionNumber()) : "LATEST")); } } catch (RepositoryException e) { throw new RulesRepositoryException(e); } String[] existingDependencies = getStringPropertyArray(DEPENDENCIES_PROPERTY_NAME); for (String existingDependency : existingDependencies) { String path = decodeDependencyPath(existingDependency)[0]; if (result.containsKey(path)) { result.put(path, existingDependency); } } return result.values().toArray(new String[result.size()]); } public void updateDependency(String dependencyPath) { String[] existingDependencies = getStringPropertyArray(DEPENDENCIES_PROPERTY_NAME); boolean found = false; for (int i = 0; i < existingDependencies.length; i++) { if (decodeDependencyPath(existingDependencies[i])[0] .equals(decodeDependencyPath(dependencyPath)[0])) { found = true; existingDependencies[i] = dependencyPath; this.updateStringArrayProperty(existingDependencies, DEPENDENCIES_PROPERTY_NAME, false); break; } } if (!found) { String[] newDependencies = new String[existingDependencies.length + 1]; System.arraycopy(existingDependencies, 0, newDependencies, 0, existingDependencies.length); newDependencies[existingDependencies.length] = dependencyPath; this.updateStringArrayProperty(newDependencies, DEPENDENCIES_PROPERTY_NAME, false); } } public static String encodeDependencyPath(String dependencyPath, String dependencyVersion) { return dependencyPath + "?version=" + dependencyVersion; } public static String[] decodeDependencyPath(String dependencyPath) { if (dependencyPath.indexOf("?version=") >= 0) { return dependencyPath.split("\\?version="); } else { return new String[]{dependencyPath, "LATEST"}; } } // The following should be kept for reference on how to add a reference that //is either locked to a version or follows head - FOR SHARING ASSETS // /** // * Adds a rule to the rule package node this object represents. The reference to the rule // * will optionally follow the head version of the specified rule's node or the specific // * current version. // * // * @param ruleItem the ruleItem corresponding to the node to add to the rule package this // * object represents // * @param followRuleHead if true, the reference to the rule node will follow the head version // * of the node, even if new versions are added. If false, will refer // * specifically to the current version. // * @throws RulesRepositoryException // */ // public void addRuleReference(RuleItem ruleItem, boolean followRuleHead) throws RulesRepositoryException { // try { // ValueFactory factory = this.node.getSession().getValueFactory(); // int i = 0; // Value[] newValueArray = null; // // try { // Value[] oldValueArray = this.node.getProperty(RULE_REFERENCE_PROPERTY_NAME).getValues(); // newValueArray = new Value[oldValueArray.length + 1]; // // for(i=0; i getAssets() { try { Node content = getVersionContentNode(); return new VersionedAssetItemIterator(content.getNode(ASSET_FOLDER_NAME).getNodes(), this.rulesRepository, this.getDependencies()); } catch (RepositoryException e) { throw new RulesRepositoryException(e); } } /** * This will query any assets stored under this package. For example, you * can pass in "drools:format = 'drl'" to get a list of only a * certain type of asset. * * @param fieldPredicates A predicate string (SQL style). * @return A list of matches. */ public AssetItemIterator queryAssets(String fieldPredicates, boolean seekArchived) { try { String sql; if (isHistoricalVersion()) { sql = "SELECT * FROM nt:frozenNode"; } else { sql = "SELECT * FROM " + AssetItem.RULE_NODE_TYPE_NAME; } sql += " WHERE jcr:path LIKE '" + getVersionContentNode().getPath() + "/" + ASSET_FOLDER_NAME + "[%]/%'"; if (fieldPredicates.length() > 0) { sql += " and " + fieldPredicates; } if (!seekArchived) { sql += " AND " + AssetItem.CONTENT_PROPERTY_ARCHIVE_FLAG + " = 'false'"; } sql += " ORDER BY " + AssetItem.TITLE_PROPERTY_NAME; //Adding this explicit order by ensures NodeIterator.getSize() returns a value other than -1. //See http://markmail.org/message/mxmk5hkxrdtcc3hl sql += ", jcr:score DESC"; Query q = node.getSession().getWorkspace().getQueryManager().createQuery(sql, Query.SQL); long time = System.currentTimeMillis(); QueryResult res = q.execute(); NodeIterator it = res.getNodes(); long taken = System.currentTimeMillis() - time; if (taken > 2000) { log.debug("QueryExec time is: " + (System.currentTimeMillis() - time)); log.debug("SQL is " + sql); log.debug(it.getClass().getName()); } //return new AssetItemIterator(it, this.rulesRepository); return new VersionedAssetItemIterator(it, this.rulesRepository, this.getDependencies()); } catch (RepositoryException e) { throw new RulesRepositoryException(e); } } public AssetItemIterator queryAssets(String fieldPredicates) { return queryAssets(fieldPredicates, false); } public AssetItemIterator listArchivedAssets() { return queryAssets(AssetItem.CONTENT_PROPERTY_ARCHIVE_FLAG + " = 'true'", true); } public AssetItemIterator listAssetsByFormat(List formatInList) { return listAssetsByFormat(formatInList.toArray(new String[formatInList.size()])); } /** * @return The header contents as pertains to a package of rule assets. */ // public String getHeader() { // return this.getStringProperty( HEADER_PROPERTY_NAME ); // } // public void updateHeader(String header) { // updateStringProperty( header, HEADER_PROPERTY_NAME ); public AssetItemIterator listAssetsWithVersionsSpecifiedByDependenciesByFormat(String... assetFormats) { AssetItemIterator assetItemIterator = listAssetsByFormat(assetFormats); ((VersionedAssetItemIterator) assetItemIterator).setReturnAssetsWithVersionsSpecifiedByDependencies(true); return assetItemIterator; } /** * This will load an iterator for assets of the given format type. */ public AssetItemIterator listAssetsByFormat(String... formats) { if (formats.length == 1) { return queryAssets(FORMAT_PROPERTY_NAME + "='" + formats[0] + "'"); } else { StringBuilder predicateBuilder = new StringBuilder(" ( "); for (int i = 0; i < formats.length; i++) { predicateBuilder.append(FORMAT_PROPERTY_NAME).append("='").append(formats[i]).append("'"); if (i != formats.length - 1) { predicateBuilder.append(" OR "); } } predicateBuilder.append(" ) "); return queryAssets(predicateBuilder.toString()); } } public AssetItemIterator listAssetsNotOfFormat(String[] formats) { if (formats.length == 1) { return queryAssets("not drools:format='" + formats[0] + "'"); } else { StringBuilder predicateBuilder = new StringBuilder("not ( "); for (int i = 0; i < formats.length; i++) { predicateBuilder.append("drools:format='").append(formats[i]).append("'"); if (!(i == formats.length - 1)) { predicateBuilder.append(" OR "); } } predicateBuilder.append(" ) "); return queryAssets(predicateBuilder.toString()); } } /** * Load a specific rule asset by name. */ public AssetItem loadAsset(String name) { try { Node content = getVersionContentNode(); return new AssetItem( this.rulesRepository, content.getNode(ASSET_FOLDER_NAME).getNode(name)); } catch (RepositoryException e) { throw new RulesRepositoryException(e); } } /** * Load a specific rule asset by name. */ public AssetItem loadAsset(String name, long versionNumber) { AssetItem asset = loadAsset(name); AssetHistoryIterator it = asset.getHistory(); while (it.hasNext()) { AssetItem historical = it.next(); long version = historical.getVersionNumber(); if (version == versionNumber) { return historical; } } throw new RulesRepositoryException( "Unable to load asset [" + name + "] with version[" + versionNumber + "]"); } /** * Returns true if this package item contains an asset of the given name. */ public boolean containsAsset(String name) { Node content; try { content = getVersionContentNode(); return content.getNode(ASSET_FOLDER_NAME).hasNode(name); } catch (RepositoryException e) { throw new RulesRepositoryException(e); } } /** * Nicely formats the information contained by the node that this object * encapsulates */ public String toString() { try { return "Content of the rule package named " + this.node.getName() + ":" + "Description: " + this.getDescription() + "\n" + "Format: " + this.getFormat() + "\n" + "Last modified: " + this.getLastModified() + "\n" + "Title: " + this.getTitle() + "\n" + "----\n"; } catch (Exception e) { log.error("Caught Exception", e); return ""; } } /** * @return An iterator over the nodes history. */ public PackageHistoryIterator getHistory() { return new PackageHistoryIterator(this.rulesRepository, this.node); } @Override public PackageItem getPrecedingVersion() throws RulesRepositoryException { try { Node precedingVersionNode = this.getPrecedingVersionNode(); if (precedingVersionNode != null) { return new PackageItem(this.rulesRepository, precedingVersionNode); } else { return null; } } catch (Exception e) { log.error("Caught exception", e); throw new RulesRepositoryException(e); } } @Override public PackageItem getSucceedingVersion() throws RulesRepositoryException { try { Node succeedingVersionNode = this.getSucceedingVersionNode(); if (succeedingVersionNode != null) { return new PackageItem(this.rulesRepository, succeedingVersionNode); } else { return null; } } catch (Exception e) { log.error("Caught exception", e); throw new RulesRepositoryException(e); } } /** * This will return a list of assets for a given state. It works through the * assets that belong to this package, and if they are not in the correct * state, walks backwards until it finds one in the correct state. *

* If it walks all the way back up the versions looking for the "latest" * version with the appropriate state, and can't find one, that asset is not * included in the result. *

* This will exclude any items that have the "ignoreState" set (so for * example, retired items, invalid items etc). * * @param state The state of assets to retrieve. * @param ignoreState The statuses to not include in the results (it will look at * the status of the latest one). */ public Iterator getAssetsWithStatus(final StateItem state, final StateItem ignoreState) { List result = new LinkedList(); for (Iterator rules = getAssets(); rules.hasNext(); ) { AssetItem head = rules.next(); if (head.sameState(state)) { result.add(head); } else if (head.sameState(ignoreState)) { //ignore this one } else { List fullHistory = new LinkedList(); for (Iterator iter = head.getHistory(); iter.hasNext(); ) { AssetItem element = iter.next(); if (!(element.getVersionNumber() == 0)) { fullHistory.add(element); } } sortHistoryByVersionNumber(fullHistory); for (AssetItem prevRule : fullHistory) { if (prevRule.sameState(state)) { result.add(prevRule); break; } } } } return result.iterator(); } void sortHistoryByVersionNumber(List fullHistory) { Collections.sort(fullHistory, new Comparator() { public int compare(AssetItem a1, AssetItem a2) { long la1 = a1.getVersionNumber(); long la2 = a2.getVersionNumber(); return la1 == la2 ? 0 : (la1 < la2 ? 1 : -1); } }); } /** * This will return a list of assets for a given state. It works through the * assets that belong to this package, and if they are not in the correct * state, walks backwards until it finds one in the correct state. *

* If it walks all the way back up the versions looking for the "latest" * version with the appropriate state, and can't find one, that asset is not * included in the result. */ public Iterator getAssetsWithStatus(final StateItem state) { return getAssetsWithStatus(state, null); } /** * @return The external URI which will be used to sync this package to an * external resource. Generally this will resolve to a directory in * (for example) Subversion - with each asset being a file (with the * format property as the file extension). */ public String getExternalURI() { return this.getStringProperty(EXTERNAL_URI_PROPERTY_NAME); } // } public void updateExternalURI(String uri) { updateStringProperty(uri, EXTERNAL_URI_PROPERTY_NAME); } public void setCatRules(String map) { updateStringProperty(map, CATEGORY_RULE_KEYS_PROPERTY_NAME); } public void updateCategoryRules(String keys, String values) throws RulesRepositoryException { //System.out.println("(updateCategoryRules) keys: " + keys + " Values: " + values ); try { this.checkout(); this.updateStringProperty(keys, CATEGORY_RULE_KEYS_PROPERTY_NAME); this.updateStringProperty(values, CATEGORY_RULE_VALUES_PROPERTY_NAME); } catch (Exception e) { log.error("Caught Exception", e); throw new RulesRepositoryException(e); } } private static HashMap convertFromObjectGraphs(final String[] keys, final String[] values) { HashMap hash = new HashMap(); for (int i = 0; i < keys.length; i++) { hash.put(keys[i], values[i]); } return hash; } public String[] convertStringToArray(String tagName) { //System.out.println("(convertStringToArray) Tags: " + tagName); List list = new ArrayList(); StringTokenizer tok = new StringTokenizer(tagName, ","); while (tok.hasMoreTokens()) { String currentTagName = tok.nextToken(); list.add(currentTagName); } return list.toArray(new String[0]); } public HashMap getCategoryRules() { return convertFromObjectGraphs(convertStringToArray(getCategoryRules(true)), convertStringToArray(getCategoryRules(false))); } public String getCategoryRules(boolean keys) { if (keys) { return getStringProperty(CATEGORY_RULE_KEYS_PROPERTY_NAME); } return getStringProperty(CATEGORY_RULE_VALUES_PROPERTY_NAME); } /** * Update the checkin comment. */ public void updateCheckinComment(String comment) { updateStringProperty(comment, VersionableItem.CHECKIN_COMMENT); } /** * This will change the status of this package, and all the contained * assets. No new versions are created of anything. * * @param newState The status tag to change it to. */ public void changeStatus(String newState) { StateItem stateItem = rulesRepository.getState(newState); updateState(stateItem); for (Iterator iter = getAssets(); iter.hasNext(); ) { iter.next().updateState(stateItem); } } /** * If the asset is a binary asset, then use this to update the content (do * NOT use text). */ public PackageItem updateCompiledPackage(InputStream data) { checkout(); try { Binary binary = this.node.getSession().getValueFactory().createBinary(data); this.node.setProperty(COMPILED_PACKAGE_PROPERTY_NAME, binary); this.node.setProperty(LAST_MODIFIED_PROPERTY_NAME, Calendar.getInstance()); return this; } catch (RepositoryException e) { log.error("Unable to update the assets binary content", e); throw new RulesRepositoryException(e); } } /** * This is a convenience method for returning the binary data as a byte * array. */ public byte[] getCompiledPackageBytes() { try { Node ruleNode = getVersionContentNode(); if (ruleNode.hasProperty(COMPILED_PACKAGE_PROPERTY_NAME)) { Property data = ruleNode.getProperty(COMPILED_PACKAGE_PROPERTY_NAME); InputStream in = data.getBinary().getStream(); // Create the byte array to hold the data byte[] bytes = new byte[(int) data.getLength()]; // Read in the bytes int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = in.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } // Ensure all the bytes have been read in if (offset < bytes.length) { throw new RulesRepositoryException("Could not completely read binary package for " + getName()); } // Close the input stream and return bytes in.close(); return bytes; } else { return null; } } catch (Exception e) { log.error(e.getMessage(), e); if (e instanceof RuntimeException) throw (RuntimeException) e; throw new RulesRepositoryException(e); } } /** * Creates a nested package. */ public PackageItem createSubPackage(String subPackageName) throws RepositoryException { this.checkout(); log.info("USER: {} CREATEING subpackage [{}] under [{}]", new Object[]{getCurrentUserName(), subPackageName, getName()}); Node subPkgsNode; try { subPkgsNode = node.getNode(RulesRepository.RULE_PACKAGE_AREA); } catch (PathNotFoundException e) { subPkgsNode = node.addNode(RulesRepository.RULE_PACKAGE_AREA, "nt:folder"); } // subPkgsNode.checkout(); String assetPath = NodeUtils.makeJSR170ComplaintName(subPackageName); Node ruleSubPackageNode = subPkgsNode.addNode(assetPath, PackageItem.RULE_PACKAGE_TYPE_NAME); ruleSubPackageNode.addNode(PackageItem.ASSET_FOLDER_NAME, "drools:versionableAssetFolder"); ruleSubPackageNode.setProperty(PackageItem.TITLE_PROPERTY_NAME, subPackageName); ruleSubPackageNode.setProperty(AssetItem.DESCRIPTION_PROPERTY_NAME, ""); ruleSubPackageNode.setProperty(AssetItem.FORMAT_PROPERTY_NAME, PackageItem.PACKAGE_FORMAT); ruleSubPackageNode.setProperty(PackageItem.CREATOR_PROPERTY_NAME, this.rulesRepository.getSession().getUserID()); Calendar lastModified = Calendar.getInstance(); ruleSubPackageNode.setProperty(PackageItem.LAST_MODIFIED_PROPERTY_NAME, lastModified); ruleSubPackageNode.setProperty(PackageItem.CONTENT_PROPERTY_ARCHIVE_FLAG, false); return new PackageItem(this.rulesRepository, ruleSubPackageNode); } /** * Returns a {@link PackageIterator} of its children * * @return a {@link PackageIterator} of its children */ public PackageIterator listSubPackages() { try { return new PackageIterator(getRulesRepository(), node.getNode(RulesRepository.RULE_PACKAGE_AREA).getNodes()); } catch (PathNotFoundException e) { return new PackageIterator(); } catch (RepositoryException e) { throw new RulesRepositoryException(e); } } private String getCurrentUserName() { return this.rulesRepository.getSession().getUserID(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy