001: package org.drools.brms.server;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.io.ByteArrayInputStream;
020: import java.io.ByteArrayOutputStream;
021: import java.io.IOException;
022: import java.io.ObjectOutputStream;
023: import java.text.DateFormat;
024: import java.util.ArrayList;
025: import java.util.Calendar;
026: import java.util.Collections;
027: import java.util.Comparator;
028: import java.util.Date;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.regex.Matcher;
032: import java.util.regex.Pattern;
033:
034: import javax.jcr.RepositoryException;
035:
036: import org.apache.log4j.Logger;
037: import org.drools.brms.client.common.AssetFormats;
038: import org.drools.brms.client.modeldriven.SuggestionCompletionEngine;
039: import org.drools.brms.client.rpc.BuilderResult;
040: import org.drools.brms.client.rpc.MetaData;
041: import org.drools.brms.client.rpc.PackageConfigData;
042: import org.drools.brms.client.rpc.RepositoryService;
043: import org.drools.brms.client.rpc.RuleAsset;
044: import org.drools.brms.client.rpc.SnapshotInfo;
045: import org.drools.brms.client.rpc.TableConfig;
046: import org.drools.brms.client.rpc.TableDataResult;
047: import org.drools.brms.client.rpc.TableDataRow;
048: import org.drools.brms.client.rpc.ValidatedResponse;
049: import org.drools.brms.server.builder.BRMSPackageBuilder;
050: import org.drools.brms.server.builder.ContentAssemblyError;
051: import org.drools.brms.server.builder.ContentPackageAssembler;
052: import org.drools.brms.server.contenthandler.ContentHandler;
053: import org.drools.brms.server.contenthandler.IRuleAsset;
054: import org.drools.brms.server.contenthandler.IValidating;
055: import org.drools.brms.server.util.BRMSSuggestionCompletionLoader;
056: import org.drools.brms.server.util.MetaDataMapper;
057: import org.drools.brms.server.util.TableDisplayHandler;
058: import org.drools.compiler.PackageBuilderConfiguration;
059: import org.drools.repository.AssetHistoryIterator;
060: import org.drools.repository.AssetItem;
061: import org.drools.repository.AssetItemIterator;
062: import org.drools.repository.CategoryItem;
063: import org.drools.repository.PackageItem;
064: import org.drools.repository.RulesRepository;
065: import org.drools.repository.RulesRepositoryAdministrator;
066: import org.drools.repository.RulesRepositoryException;
067: import org.drools.repository.StateItem;
068: import org.drools.repository.VersionableItem;
069: import org.jboss.seam.annotations.AutoCreate;
070: import org.jboss.seam.annotations.In;
071: import org.jboss.seam.annotations.Name;
072: import org.jboss.seam.annotations.WebRemote;
073: import org.jboss.seam.annotations.security.Restrict;
074:
075: import com.google.gwt.user.client.rpc.SerializableException;
076:
077: /**
078: * This is the implementation of the repository service to drive the GWT based front end.
079: *
080: * @author Michael Neale
081: */
082: @Name("org.drools.brms.client.rpc.RepositoryService")
083: @AutoCreate
084: public class ServiceImplementation implements RepositoryService {
085:
086: @In
087: public RulesRepository repository;
088:
089: private static final long serialVersionUID = 400L;
090: private static final DateFormat dateFormatter = DateFormat
091: .getInstance();
092: private static final Logger log = Logger
093: .getLogger(ServiceImplementation.class);
094: private MetaDataMapper metaDataMapper = new MetaDataMapper();
095:
096: @WebRemote
097: @Restrict("#{identity.loggedIn}")
098: public String[] loadChildCategories(String categoryPath) {
099:
100: CategoryItem item = repository.loadCategory(categoryPath);
101: List children = item.getChildTags();
102: String[] list = new String[children.size()];
103: for (int i = 0; i < list.length; i++) {
104: list[i] = ((CategoryItem) children.get(i)).getName();
105: }
106: return list;
107:
108: }
109:
110: @WebRemote
111: @Restrict("#{identity.loggedIn}")
112: public Boolean createCategory(String path, String name,
113: String description) {
114:
115: log.info("USER:" + repository.getSession().getUserID()
116: + " CREATING cateogory: [" + name + "] in path ["
117: + path + "]");
118:
119: if (path == null || "".equals(path)) {
120: path = "/";
121: }
122:
123: CategoryItem item = repository.loadCategory(path);
124: item.addCategory(name, description);
125: repository.save();
126: return Boolean.TRUE;
127: }
128:
129: /**
130: * This will create a new asset. It will be saved, but not checked in.
131: * The initial state will be the draft state.
132: */
133: @WebRemote
134: @Restrict("#{identity.loggedIn}")
135: public String createNewRule(String ruleName, String description,
136: String initialCategory, String initialPackage, String format)
137: throws SerializableException {
138:
139: log.info("USER:" + repository.getSession().getUserID()
140: + " CREATING new asset name [" + ruleName
141: + "] in package [" + initialPackage + "]");
142:
143: try {
144:
145: PackageItem pkg = repository.loadPackage(initialPackage);
146: AssetItem asset = pkg.addAsset(ruleName, description,
147: initialCategory, format);
148:
149: applyPreBuiltTemplates(ruleName, format, asset);
150: repository.save();
151:
152: return asset.getUUID();
153: } catch (RulesRepositoryException e) {
154: throw new SerializableException(e.getMessage());
155: }
156:
157: }
158:
159: @WebRemote
160: @Restrict("#{identity.loggedIn}")
161: public void deleteUncheckedRule(String uuid, String initialPackage) {
162: AssetItem asset = repository.loadAssetByUUID(uuid);
163: asset.remove();
164: repository.save();
165: }
166:
167: /**
168: * For some format types, we add some sugar by adding a new template.
169: */
170: private void applyPreBuiltTemplates(String ruleName, String format,
171: AssetItem asset) {
172: if (format.equals(AssetFormats.DSL_TEMPLATE_RULE)) {
173: asset.updateContent("when\n\nthen\n");
174: asset
175: .updateDescription("A dsl is a language mapping from a domain specific language to the rule language.");
176: } else if (format.equals(AssetFormats.FUNCTION)) {
177: asset.updateContent("function <returnType> " + ruleName
178: + "(<args here>) {\n\n\n}");
179: } else if (format.equals(AssetFormats.DSL)) {
180: asset
181: .updateContent("[when]Condition sentence template {var}="
182: + "rule language mapping {var}\n"
183: + "[then]Action sentence template=rule language mapping");
184: } else if (format.equals(AssetFormats.DECISION_SPREADSHEET_XLS)) {
185: asset.updateBinaryContentAttachment(this .getClass()
186: .getResourceAsStream("/SampleDecisionTable.xls"));
187: asset
188: .updateBinaryContentAttachmentFileName("SampleDecisionTable.xls");
189: } else if (format.equals(AssetFormats.ENUMERATION)) {
190: asset
191: .updateDescription("An enumeration is a mapping from fields to a list of values."
192: + "This will mean the rule editor will show a drop down for fields, instead of a text box."
193: + "The format of this is: 'FactType.fieldName ': ['Value1', 'Value2']\n"
194: + "You can add more mappings by adding in more lines. "
195: + "\nFor example:\n\n"
196: + "'Person.sex' : ['M', 'F']\n"
197: + "'Person.rating' : ['High', 'Low']\n\n"
198: + "You can also ad display aliases (so the value used in the rule is separate to the one displayed:\n"
199: + "'Person.sex' : ['M=Male', 'F=Female']\n"
200: + "in the above case, the 'M=Male' means that 'Male' will be displayed as an item in a drop down box, but the value 'M' will be used in the rule. ");
201: }
202: }
203:
204: @WebRemote
205: @Restrict("#{identity.loggedIn}")
206: public PackageConfigData[] listPackages() {
207: Iterator pkgs = repository.listPackages();
208: List<PackageConfigData> result = new ArrayList<PackageConfigData>();
209: while (pkgs.hasNext()) {
210: PackageItem pkg = (PackageItem) pkgs.next();
211:
212: PackageConfigData data = new PackageConfigData();
213: data.uuid = pkg.getUUID();
214: data.name = pkg.getName();
215:
216: result.add(data);
217: }
218:
219: Collections.sort(result, new Comparator<Object>() {
220:
221: public int compare(final Object o1, final Object o2) {
222: final PackageConfigData d1 = (PackageConfigData) o1;
223: final PackageConfigData d2 = (PackageConfigData) o2;
224: return d1.name.compareTo(d2.name);
225: }
226:
227: });
228: PackageConfigData[] resultArr = result
229: .toArray(new PackageConfigData[result.size()]);
230:
231: return resultArr;
232: }
233:
234: @WebRemote
235: @Restrict("#{identity.loggedIn}")
236: public TableDataResult loadRuleListForCategories(String categoryPath)
237: throws SerializableException {
238: long start = System.currentTimeMillis();
239:
240: List list = repository.findAssetsByCategory(categoryPath);
241: TableDisplayHandler handler = new TableDisplayHandler(
242: TableDisplayHandler.DEFAULT_TABLE_TEMPLATE);
243: //log.info("time for load: " + (System.currentTimeMillis() - start) );
244: return handler.loadRuleListTable(list.iterator(), -1);
245:
246: }
247:
248: @WebRemote
249: @Restrict("#{identity.loggedIn}")
250: public TableConfig loadTableConfig(String listName) {
251: TableDisplayHandler handler = new TableDisplayHandler(listName);
252: return handler.loadTableConfig();
253: }
254:
255: /**
256: * This actually does the hard work of loading up an asset based
257: * on its format.
258: */
259: @WebRemote
260: @Restrict("#{identity.loggedIn}")
261: public RuleAsset loadRuleAsset(String uuid)
262: throws SerializableException {
263:
264: AssetItem item = repository.loadAssetByUUID(uuid);
265: RuleAsset asset = new RuleAsset();
266: asset.uuid = uuid;
267:
268: //load standard meta data
269: asset.metaData = populateMetaData(item);
270:
271: // get package header
272: PackageItem pkgItem = repository
273: .loadPackage(asset.metaData.packageName);
274:
275: //load the content
276: ContentHandler handler = ContentHandler
277: .getHandler(asset.metaData.format);
278: handler.retrieveAssetContent(asset, pkgItem, item);
279:
280: return asset;
281: }
282:
283: /**
284: * read in the meta data, populating all dublin core and versioning stuff.
285: */
286: MetaData populateMetaData(VersionableItem item) {
287: MetaData meta = new MetaData();
288:
289: meta.status = (item.getState() != null) ? item.getState()
290: .getName() : "";
291:
292: metaDataMapper.copyToMetaData(meta, item);
293:
294: meta.createdDate = calendarToDate(item.getCreatedDate());
295: meta.lastModifiedDate = calendarToDate(item.getLastModified());
296:
297: return meta;
298: }
299:
300: /**
301: * Populate meta data with asset specific info.
302: */
303: MetaData populateMetaData(AssetItem item) {
304: MetaData meta = populateMetaData((VersionableItem) item);
305: meta.packageName = item.getPackageName();
306:
307: List cats = item.getCategories();
308: meta.categories = new String[cats.size()];
309: for (int i = 0; i < meta.categories.length; i++) {
310: CategoryItem cat = (CategoryItem) cats.get(i);
311: meta.categories[i] = cat.getFullPath();
312: }
313: meta.dateEffective = calendarToDate(item.getDateEffective());
314: meta.dateExpired = calendarToDate(item.getDateExpired());
315: return meta;
316:
317: }
318:
319: private Date calendarToDate(Calendar createdDate) {
320: if (createdDate == null)
321: return null;
322: return createdDate.getTime();
323: }
324:
325: private Calendar dateToCalendar(Date date) {
326: if (date == null)
327: return null;
328: Calendar cal = Calendar.getInstance();
329: cal.setTime(date);
330: return cal;
331: }
332:
333: @WebRemote
334: @Restrict("#{identity.loggedIn}")
335: public String checkinVersion(RuleAsset asset)
336: throws SerializableException {
337:
338: log.info("USER:" + repository.getSession().getUserID()
339: + " CHECKING IN asset: [" + asset.metaData.name
340: + "] UUID: [" + asset.uuid + "] ARCHIVED ["
341: + asset.archived + "]");
342:
343: AssetItem repoAsset = repository.loadAssetByUUID(asset.uuid);
344: if (asset.metaData.lastModifiedDate.before(repoAsset
345: .getLastModified().getTime())) {
346: throw new SerializableException(
347: "This asset was saved by someone else previously, and this version will not be overwritten.");
348: }
349:
350: repoAsset.archiveItem(asset.archived);
351: MetaData meta = asset.metaData;
352:
353: metaDataMapper.copyFromMetaData(meta, repoAsset);
354:
355: repoAsset
356: .updateDateEffective(dateToCalendar(meta.dateEffective));
357: repoAsset.updateDateExpired(dateToCalendar(meta.dateExpired));
358:
359: repoAsset.updateCategoryList(meta.categories);
360: ContentHandler handler = ContentHandler.getHandler(repoAsset
361: .getFormat());//new AssetContentFormatHandler();
362: handler.storeAssetContent(asset, repoAsset);
363:
364: repoAsset.checkin(meta.checkinComment);
365:
366: return repoAsset.getUUID();
367: }
368:
369: @WebRemote
370: @Restrict("#{identity.loggedIn}")
371: public TableDataResult loadAssetHistory(String uuid)
372: throws SerializableException {
373:
374: List<TableDataRow> result = new ArrayList<TableDataRow>();
375:
376: AssetItem item = repository.loadAssetByUUID(uuid);
377: AssetHistoryIterator it = item.getHistory();
378:
379: while (it.hasNext()) {
380: AssetItem historical = (AssetItem) it.next();//new AssetItem(repo, element);
381: long versionNumber = historical.getVersionNumber();
382: if (!(versionNumber == 0)
383: && !(versionNumber == item.getVersionNumber())) {
384: TableDataRow row = new TableDataRow();
385: row.id = historical.getVersionSnapshotUUID();
386: row.values = new String[4];
387: row.values[0] = Long.toString(historical
388: .getVersionNumber());
389: row.values[1] = historical.getCheckinComment();
390: row.values[2] = dateFormatter.format(historical
391: .getLastModified().getTime());
392: row.values[3] = historical.getStateDescription();
393: result.add(row);
394: }
395: }
396:
397: if (result.size() == 0)
398: return null;
399: TableDataResult table = new TableDataResult();
400: table.data = result.toArray(new TableDataRow[result.size()]);
401:
402: return table;
403: }
404:
405: @WebRemote
406: @Restrict("#{identity.loggedIn}")
407: public TableDataResult loadArchivedAssets()
408: throws SerializableException {
409:
410: List<TableDataRow> result = new ArrayList<TableDataRow>();
411:
412: AssetItemIterator it = repository.findArchivedAssets();
413:
414: while (it.hasNext()) {
415: AssetItem archived = (AssetItem) it.next();
416:
417: TableDataRow row = new TableDataRow();
418: row.id = archived.getUUID();
419: row.values = new String[5];
420:
421: row.values[0] = archived.getFormat();
422: row.values[1] = archived.getPackageName();
423: row.values[2] = archived.getName();
424: row.values[3] = archived.getLastContributor();
425: row.values[4] = archived.getLastModified().getTime()
426: .toLocaleString();
427:
428: result.add(row);
429: }
430:
431: if (result.size() == 0) {
432: return null;
433: }
434:
435: TableDataResult table = new TableDataResult();
436: table.data = result.toArray(new TableDataRow[result.size()]);
437:
438: return table;
439: }
440:
441: @WebRemote
442: @Restrict("#{identity.loggedIn}")
443: public void restoreVersion(String versionUUID, String assetUUID,
444: String comment) {
445: AssetItem old = repository.loadAssetByUUID(versionUUID);
446: AssetItem head = repository.loadAssetByUUID(assetUUID);
447:
448: log.info("USER:" + repository.getSession().getUserID()
449: + " RESTORE of asset: [" + head.getName() + "] UUID: ["
450: + head.getUUID()
451: + "] with historical version number: ["
452: + old.getVersionNumber());
453:
454: repository.restoreHistoricalAsset(old, head, comment);
455:
456: }
457:
458: @WebRemote
459: @Restrict("#{identity.loggedIn}")
460: public byte[] exportRepository() throws SerializableException {
461:
462: log.info("USER:" + repository.getSession().getUserID()
463: + " EXPORTING repository");
464:
465: byte[] exportedOutput = null;
466: try {
467: exportedOutput = repository.exportRulesRepository();
468: } catch (Exception e) {
469: throw new SerializableException(
470: "Unable to export repository");
471: }
472: return exportedOutput;
473: }
474:
475: @WebRemote
476: @Restrict("#{identity.loggedIn}")
477: public String createPackage(String name, String description)
478: throws SerializableException {
479: log.info("USER:" + repository.getSession().getUserID()
480: + " CREATING package [" + name + "]");
481: PackageItem item = repository.createPackage(name, description);
482:
483: return item.getUUID();
484: }
485:
486: @WebRemote
487: @Restrict("#{identity.loggedIn}")
488: public PackageConfigData loadPackageConfig(String uuid) {
489: PackageItem item = repository.loadPackageByUUID(uuid);
490:
491: PackageConfigData data = new PackageConfigData();
492: data.uuid = item.getUUID();
493: data.header = item.getHeader();
494: data.externalURI = item.getExternalURI();
495: data.description = item.getDescription();
496: data.name = item.getName();
497: data.lastModified = item.getLastModified().getTime();
498: data.dateCreated = item.getCreatedDate().getTime();
499: data.checkinComment = item.getCheckinComment();
500: data.lasContributor = item.getLastContributor();
501: data.state = item.getStateDescription();
502: data.isSnapshot = item.isSnapshot();
503: if (data.isSnapshot) {
504: data.snapshotName = item.getSnapshotName();
505: }
506: return data;
507: }
508:
509: @WebRemote
510: @Restrict("#{identity.loggedIn}")
511: public ValidatedResponse savePackage(PackageConfigData data)
512: throws SerializableException {
513: log.info("USER:" + repository.getSession().getUserID()
514: + " SAVING package [" + data.name + "]");
515:
516: PackageItem item = repository.loadPackage(data.name);
517:
518: item.updateHeader(data.header);
519: item.updateExternalURI(data.externalURI);
520: item.updateDescription(data.description);
521: item.archiveItem(data.archived);
522:
523: item.checkin(data.description);
524:
525: BRMSSuggestionCompletionLoader loader = new BRMSSuggestionCompletionLoader();
526: loader.getSuggestionEngine(item);
527:
528: ValidatedResponse res = new ValidatedResponse();
529: if (loader.hasErrors()) {
530: res.hasErrors = true;
531: String err = "";
532: for (Iterator iter = loader.getErrors().iterator(); iter
533: .hasNext();) {
534: err += (String) iter.next();
535: if (iter.hasNext())
536: err += "\n";
537: }
538: res.errorHeader = "Package validation errors";
539: res.errorMessage = err;
540: }
541:
542: return res;
543: }
544:
545: @WebRemote
546: @Restrict("#{identity.loggedIn}")
547: public TableDataResult listAssets(String uuid, String formats[],
548: int numRows, int startRow) throws SerializableException {
549: long start = System.currentTimeMillis();
550: PackageItem pkg = repository.loadPackageByUUID(uuid);
551: AssetItemIterator it = pkg.listAssetsByFormat(formats);
552: if (numRows != -1) {
553: it.skip(startRow);
554: }
555: TableDisplayHandler handler = new TableDisplayHandler(
556: TableDisplayHandler.DEFAULT_TABLE_TEMPLATE);
557: log.debug("time for asset list load: "
558: + (System.currentTimeMillis() - start));
559: return handler.loadRuleListTable(it, numRows);
560: }
561:
562: @WebRemote
563: @Restrict("#{identity.loggedIn}")
564: public String createState(String name) throws SerializableException {
565: log.info("USER:" + repository.getSession().getUserID()
566: + " CREATING state: [" + name + "]");
567: try {
568: String uuid = repository.createState(name).getNode()
569: .getUUID();
570: repository.save();
571: return uuid;
572: } catch (RepositoryException e) {
573: throw new SerializableException(
574: "Unable to create the status.");
575: }
576: }
577:
578: @WebRemote
579: @Restrict("#{identity.loggedIn}")
580: public String[] listStates() throws SerializableException {
581: StateItem[] states = repository.listStates();
582: String[] result = new String[states.length];
583: for (int i = 0; i < states.length; i++) {
584: result[i] = states[i].getName();
585: }
586: return result;
587: }
588:
589: @WebRemote
590: @Restrict("#{identity.loggedIn}")
591: public void changeState(String uuid, String newState,
592: boolean wholePackage) {
593:
594: if (!wholePackage) {
595:
596: AssetItem asset = repository.loadAssetByUUID(uuid);
597: log.info("USER:" + repository.getSession().getUserID()
598: + " CHANGING ASSET STATUS. Asset name, uuid: "
599: + "[" + asset.getName() + ", " + asset.getUUID()
600: + "]" + " to [" + newState + "]");
601: asset.updateState(newState);
602: } else {
603: PackageItem pkg = repository.loadPackageByUUID(uuid);
604: log.info("USER:" + repository.getSession().getUserID()
605: + " CHANGING Package STATUS. Asset name, uuid: "
606: + "[" + pkg.getName() + ", " + pkg.getUUID() + "]"
607: + " to [" + newState + "]");
608: pkg.changeStatus(newState);
609: }
610: repository.save();
611: }
612:
613: @WebRemote
614: @Restrict("#{identity.loggedIn}")
615: public void changeAssetPackage(String uuid, String newPackage,
616: String comment) {
617: log.info("USER:" + repository.getSession().getUserID()
618: + " CHANGING PACKAGE OF asset: [" + uuid + "] to ["
619: + newPackage + "]");
620: repository.moveRuleItemPackage(newPackage, uuid, comment);
621:
622: }
623:
624: @WebRemote
625: @Restrict("#{identity.loggedIn}")
626: public String copyAsset(String assetUUID, String newPackage,
627: String newName) {
628: return repository.copyAsset(assetUUID, newPackage, newName);
629: }
630:
631: @WebRemote
632: @Restrict("#{identity.loggedIn}")
633: public SnapshotInfo[] listSnapshots(String packageName) {
634:
635: String[] snaps = repository.listPackageSnapshots(packageName);
636: SnapshotInfo[] res = new SnapshotInfo[snaps.length];
637: for (int i = 0; i < snaps.length; i++) {
638: PackageItem snap = repository.loadPackageSnapshot(
639: packageName, snaps[i]);
640: SnapshotInfo info = new SnapshotInfo();
641: res[i] = info;
642: info.comment = snap.getCheckinComment();
643: info.name = snaps[i];
644: info.uuid = snap.getUUID();
645: }
646: return res;
647: }
648:
649: @WebRemote
650: @Restrict("#{identity.loggedIn}")
651: public void createPackageSnapshot(String packageName,
652: String snapshotName, boolean replaceExisting, String comment) {
653: log.info("USER:" + repository.getSession().getUserID()
654: + " CREATING PACKAGE SNAPSHOT for package: ["
655: + packageName + "] snapshot name: [" + snapshotName);
656:
657: if (replaceExisting) {
658: repository.removePackageSnapshot(packageName, snapshotName);
659: }
660:
661: repository.createPackageSnapshot(packageName, snapshotName);
662: PackageItem item = repository.loadPackageSnapshot(packageName,
663: snapshotName);
664: item.updateCheckinComment(comment);
665: repository.save();
666:
667: }
668:
669: @WebRemote
670: @Restrict("#{identity.loggedIn}")
671: public void copyOrRemoveSnapshot(String packageName,
672: String snapshotName, boolean delete, String newSnapshotName)
673: throws SerializableException {
674:
675: if (delete) {
676: log.info("USER:" + repository.getSession().getUserID()
677: + " REMOVING SNAPSHOT for package: [" + packageName
678: + "] snapshot: [" + snapshotName + "]");
679: repository.removePackageSnapshot(packageName, snapshotName);
680: } else {
681: if (newSnapshotName.equals("")) {
682: throw new SerializableException(
683: "Need to have a new snapshot name.");
684: }
685: log.info("USER:" + repository.getSession().getUserID()
686: + " COPYING SNAPSHOT for package: [" + packageName
687: + "] snapshot: [" + snapshotName + "] to ["
688: + newSnapshotName + "]");
689:
690: repository.copyPackageSnapshot(packageName, snapshotName,
691: newSnapshotName);
692: }
693:
694: }
695:
696: @WebRemote
697: @Restrict("#{identity.loggedIn}")
698: public TableDataResult quickFindAsset(String searchText, int max,
699: boolean searchArchived) {
700:
701: String search = Pattern.compile("*", Pattern.LITERAL).matcher(
702: searchText).replaceAll(Matcher.quoteReplacement("%"));
703:
704: if (!search.endsWith("%")) {
705: search += "%";
706: }
707:
708: TableDataResult result = new TableDataResult();
709:
710: List<TableDataRow> resultList = new ArrayList<TableDataRow>();
711:
712: long start = System.currentTimeMillis();
713: AssetItemIterator it = repository.findAssetsByName(search,
714: searchArchived); // search for archived items
715: log.debug("Search time: "
716: + (System.currentTimeMillis() - start));
717: for (int i = 0; i < max; i++) {
718: if (!it.hasNext()) {
719: break;
720: }
721:
722: AssetItem item = (AssetItem) it.next();
723: TableDataRow row = new TableDataRow();
724: row.id = item.getUUID();
725: String desc = item.getDescription() + "";
726: row.values = new String[] { item.getName(),
727: desc.substring(0, Math.min(32, desc.length())) };
728: resultList.add(row);
729:
730: }
731:
732: if (it.hasNext()) {
733: TableDataRow empty = new TableDataRow();
734: empty.id = "MORE";
735: resultList.add(empty);
736: }
737:
738: result.data = resultList.toArray(new TableDataRow[resultList
739: .size()]);
740: return result;
741:
742: }
743:
744: @WebRemote
745: @Restrict("#{identity.loggedIn}")
746: public void removeCategory(String categoryPath)
747: throws SerializableException {
748: log.info("USER:" + repository.getSession().getUserID()
749: + " REMOVING CATEGORY path: [" + categoryPath + "]");
750:
751: try {
752: repository.loadCategory(categoryPath).remove();
753: repository.save();
754: } catch (RulesRepositoryException e) {
755: throw new SerializableException(e.getMessage());
756: }
757: }
758:
759: @WebRemote
760: @Restrict("#{identity.loggedIn}")
761: public void clearRulesRepository() {
762: RulesRepositoryAdministrator admin = new RulesRepositoryAdministrator(
763: repository.getSession());
764: admin.clearRulesRepository();
765: }
766:
767: @WebRemote
768: @Restrict("#{identity.loggedIn}")
769: public SuggestionCompletionEngine loadSuggestionCompletionEngine(
770: String packageName) throws SerializableException {
771: try {
772:
773: PackageItem pkg = repository.loadPackage(packageName);
774: BRMSSuggestionCompletionLoader loader = new BRMSSuggestionCompletionLoader();
775: return loader.getSuggestionEngine(pkg);
776: } catch (RulesRepositoryException e) {
777: log.error(e);
778: throw new SerializableException(e.getMessage());
779: }
780:
781: }
782:
783: @WebRemote
784: @Restrict("#{identity.loggedIn}")
785: public BuilderResult[] buildPackage(String packageUUID,
786: String selectorConfigName) throws SerializableException {
787: PackageItem item = repository.loadPackageByUUID(packageUUID);
788: ContentPackageAssembler asm = new ContentPackageAssembler(item,
789: selectorConfigName);
790: if (asm.hasErrors()) {
791: BuilderResult[] result = generateBuilderResults(asm);
792: return result;
793: } else {
794: try {
795: ByteArrayOutputStream bout = new ByteArrayOutputStream();
796: ObjectOutputStream out = new ObjectOutputStream(bout);
797: out.writeObject(asm.getBinaryPackage());
798:
799: item.updateCompiledPackage(new ByteArrayInputStream(
800: bout.toByteArray()));
801: out.flush();
802: out.close();
803:
804: repository.save();
805: } catch (IOException e) {
806: log.error(e);
807: throw new SerializableException(e.getMessage());
808: }
809:
810: return null;
811:
812: }
813: }
814:
815: private BuilderResult[] generateBuilderResults(
816: ContentPackageAssembler asm) {
817: BuilderResult[] result = new BuilderResult[asm.getErrors()
818: .size()];
819: for (int i = 0; i < result.length; i++) {
820: ContentAssemblyError err = asm.getErrors().get(i);
821: BuilderResult res = new BuilderResult();
822: res.assetName = err.itemInError.getName();
823: res.assetFormat = err.itemInError.getFormat();
824: res.message = err.errorReport;
825: res.uuid = err.itemInError.getUUID();
826: result[i] = res;
827: }
828: return result;
829: }
830:
831: @WebRemote
832: @Restrict("#{identity.loggedIn}")
833: public String buildPackageSource(String packageUUID)
834: throws SerializableException {
835: PackageItem item = repository.loadPackageByUUID(packageUUID);
836: ContentPackageAssembler asm = new ContentPackageAssembler(item,
837: false);
838: return asm.getDRL();
839: }
840:
841: @WebRemote
842: @Restrict("#{identity.loggedIn}")
843: public String buildAssetSource(RuleAsset asset)
844: throws SerializableException {
845: AssetItem item = repository.loadAssetByUUID(asset.uuid);
846:
847: ContentHandler handler = ContentHandler.getHandler(item
848: .getFormat());//new AssetContentFormatHandler();
849: handler.storeAssetContent(asset, item);
850: StringBuffer buf = new StringBuffer();
851: if (handler.isRuleAsset()) {
852:
853: BRMSPackageBuilder builder = new BRMSPackageBuilder(
854: new PackageBuilderConfiguration());
855: //now we load up the DSL files
856: builder.setDSLFiles(BRMSPackageBuilder.getDSLMappingFiles(
857: item.getPackage(),
858: new BRMSPackageBuilder.DSLErrorEvent() {
859: public void recordError(AssetItem asset,
860: String message) {
861: //ignore at this point...
862: }
863: }));
864: ((IRuleAsset) handler).assembleDRL(builder, item, buf);
865: } else {
866: return item.getContent();
867: }
868:
869: return buf.toString();
870: }
871:
872: @WebRemote
873: @Restrict("#{identity.loggedIn}")
874: public BuilderResult[] buildAsset(RuleAsset asset)
875: throws SerializableException {
876: AssetItem item = repository.loadAssetByUUID(asset.uuid);
877:
878: ContentHandler handler = ContentHandler.getHandler(item
879: .getFormat());//new AssetContentFormatHandler();
880: handler.storeAssetContent(asset, item);
881:
882: if (handler instanceof IValidating) {
883: return ((IValidating) handler).validateAsset(item);
884: } else {
885:
886: ContentPackageAssembler asm = new ContentPackageAssembler(
887: item);
888: if (!asm.hasErrors()) {
889: return null;
890: } else {
891: return generateBuilderResults(asm);
892: }
893: }
894:
895: }
896:
897: @WebRemote
898: @Restrict("#{identity.loggedIn}")
899: public void copyPackage(String sourcePackageName,
900: String destPackageName) throws SerializableException {
901: try {
902: repository.copyPackage(sourcePackageName, destPackageName);
903: } catch (RulesRepositoryException e) {
904: log.error(e);
905: throw e;
906: }
907: }
908:
909: @WebRemote
910: @Restrict("#{identity.loggedIn}")
911: public String renameAsset(String uuid, String newName) {
912: return repository.renameAsset(uuid, newName);
913: }
914:
915: @WebRemote
916: @Restrict("#{identity.loggedIn}")
917: public void archiveAsset(String uuid, boolean value) {
918: try {
919: AssetItem item = repository.loadAssetByUUID(uuid);
920: item.archiveItem(value);
921: item.checkin("unarchived");
922:
923: } catch (RulesRepositoryException e) {
924: log.error(e);
925: throw e;
926: }
927: }
928:
929: @WebRemote
930: @Restrict("#{identity.loggedIn}")
931: public void removeAsset(String uuid) {
932: try {
933: AssetItem item = repository.loadAssetByUUID(uuid);
934: item.remove();
935: repository.save();
936: } catch (RulesRepositoryException e) {
937: log.error(e);
938: throw e;
939: }
940: }
941:
942: @WebRemote
943: @Restrict("#{identity.loggedIn}")
944: public String renamePackage(String uuid, String newName) {
945: return repository.renamePackage(uuid, newName);
946: }
947:
948: }
|