/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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.workbench.screens.guided.dtable.backend.server; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.inject.Named; import org.drools.workbench.models.guided.dtable.shared.model.GuidedDecisionTable52; import org.drools.workbench.screens.guided.dtable.model.GuidedDecisionTableEditorGraphContent; import org.drools.workbench.screens.guided.dtable.model.GuidedDecisionTableEditorGraphModel; import org.drools.workbench.screens.guided.dtable.service.GuidedDecisionTableEditorService; import org.drools.workbench.screens.guided.dtable.service.GuidedDecisionTableGraphEditorService; import org.drools.workbench.screens.guided.dtable.service.GuidedDecisionTableLinkManager; import org.drools.workbench.screens.guided.dtable.type.GuidedDTableResourceTypeDefinition; import org.guvnor.common.services.backend.config.SafeSessionInfo; import org.guvnor.common.services.backend.exceptions.ExceptionUtilities; import org.guvnor.common.services.backend.file.DotFileFilter; import org.guvnor.common.services.backend.util.CommentedOptionFactory; import org.guvnor.common.services.project.model.Package; import org.guvnor.common.services.shared.metadata.model.Metadata; import org.guvnor.common.services.shared.metadata.model.Overview; import org.jboss.errai.bus.server.annotations.Service; import org.kie.workbench.common.services.backend.service.KieService; import org.kie.workbench.common.services.shared.project.KieProjectService; import org.uberfire.backend.server.util.Paths; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.commons.data.Pair; import org.uberfire.ext.editor.commons.backend.version.VersionRecordService; import org.uberfire.ext.editor.commons.service.CopyService; import org.uberfire.ext.editor.commons.service.DeleteService; import org.uberfire.ext.editor.commons.service.RenameService; import org.uberfire.io.IOService; import org.uberfire.java.nio.base.version.VersionRecord; import org.uberfire.java.nio.file.DirectoryStream; import org.uberfire.java.nio.file.FileAlreadyExistsException; import org.uberfire.rpc.SessionInfo; import org.uberfire.workbench.events.ResourceOpenedEvent; @Service @ApplicationScoped public class GuidedDecisionTableGraphEditorServiceImpl extends KieService<GuidedDecisionTableEditorGraphContent> implements GuidedDecisionTableGraphEditorService { private IOService ioService; private CopyService copyService; private DeleteService deleteService; private RenameService renameService; private KieProjectService projectService; private VersionRecordService versionRecordService; private GuidedDecisionTableEditorService dtableService; private GuidedDecisionTableLinkManager dtableLinkManager; private Event<ResourceOpenedEvent> resourceOpenedEvent; private CommentedOptionFactory commentedOptionFactory; private GuidedDTableResourceTypeDefinition resourceType; private DotFileFilter dotFileFilter; private SafeSessionInfo safeSessionInfo; public GuidedDecisionTableGraphEditorServiceImpl() { //Zero parameter constructor for CDI } @Inject public GuidedDecisionTableGraphEditorServiceImpl(final @Named("ioStrategy") IOService ioService, final CopyService copyService, final DeleteService deleteService, final RenameService renameService, final KieProjectService projectService, final VersionRecordService versionRecordService, final GuidedDecisionTableEditorService dtableService, final GuidedDecisionTableLinkManager dtableLinkManager, final Event<ResourceOpenedEvent> resourceOpenedEvent, final CommentedOptionFactory commentedOptionFactory, final GuidedDTableResourceTypeDefinition resourceType, final DotFileFilter dotFileFilter, final SessionInfo sessionInfo) { this.ioService = ioService; this.copyService = copyService; this.deleteService = deleteService; this.renameService = renameService; this.projectService = projectService; this.versionRecordService = versionRecordService; this.dtableService = dtableService; this.dtableLinkManager = dtableLinkManager; this.resourceOpenedEvent = resourceOpenedEvent; this.commentedOptionFactory = commentedOptionFactory; this.resourceType = resourceType; this.dotFileFilter = dotFileFilter; this.safeSessionInfo = new SafeSessionInfo(sessionInfo); } @Override public Path create(final Path context, final String fileName, final GuidedDecisionTableEditorGraphModel model, final String comment) { try { final org.uberfire.java.nio.file.Path nioPath = Paths.convert(context).resolve(fileName); if (ioService.exists(nioPath)) { throw new FileAlreadyExistsException(nioPath.toString()); } final Set<Path> paths = getLinkedDecisionTablesInPackage(context); paths.forEach((path) -> model.getEntries().add(new GuidedDecisionTableEditorGraphModel.GuidedDecisionTableGraphEntry(path, getLatestVersionPath(path)))); ioService.write(nioPath, GuidedDTGraphXMLPersistence.getInstance().marshal(model), commentedOptionFactory.makeCommentedOption(comment)); final Path newPath = Paths.convert(nioPath); return newPath; } catch (Exception e) { throw ExceptionUtilities.handleException(e); } } @Override public GuidedDecisionTableEditorGraphModel load(final Path path) { try { final String content = ioService.readAllString(Paths.convert(path)); return GuidedDTGraphXMLPersistence.getInstance().unmarshal(content); } catch (Exception e) { throw ExceptionUtilities.handleException(e); } } @Override public GuidedDecisionTableEditorGraphContent loadContent(final Path path) { return super.loadContent(path); } @Override protected GuidedDecisionTableEditorGraphContent constructContent(final Path path, final Overview overview) { final GuidedDecisionTableEditorGraphModel model = load(path); //Signal opening to interested parties resourceOpenedEvent.fire(new ResourceOpenedEvent(path, safeSessionInfo)); return new GuidedDecisionTableEditorGraphContent(model, overview); } @Override public Path save(final Path path, final GuidedDecisionTableEditorGraphModel model, final Metadata metadata, final String comment) { try { final Metadata currentMetadata = metadataService.getMetadata(path); versionEntriesPaths(model); ioService.write(Paths.convert(path), GuidedDTGraphXMLPersistence.getInstance().marshal(model), metadataService.setUpAttributes(path, metadata), commentedOptionFactory.makeCommentedOption(comment)); fireMetadataSocialEvents(path, currentMetadata, metadata); return path; } catch (Exception e) { throw ExceptionUtilities.handleException(e); } } private void versionEntriesPaths(final GuidedDecisionTableEditorGraphModel model) { for (GuidedDecisionTableEditorGraphModel.GuidedDecisionTableGraphEntry entry : model.getEntries()) { entry.setPathVersion(getLatestVersionPath(entry.getPathHead())); } } private Path getLatestVersionPath(final Path path) { final List<VersionRecord> versions = versionRecordService.load(Paths.convert(path)); final String versionUri = versions.get(versions.size() - 1).uri(); return PathFactory.newPathBasedOn(path.getFileName(), versionUri, path); } @Override public void delete(final Path path, final String comment) { try { deleteService.delete(path, comment); } catch (Exception e) { throw ExceptionUtilities.handleException(e); } } @Override public Path rename(final Path path, final String newName, final String comment) { try { return renameService.rename(path, newName, comment); } catch (Exception e) { throw ExceptionUtilities.handleException(e); } } @Override public Path copy(final Path path, final String newName, final String comment) { try { return copyService.copy(path, newName, comment); } catch (Exception e) { throw ExceptionUtilities.handleException(e); } } @Override public Path copy(final Path path, final String newName, final Path targetDirectory, final String comment) { try { return copyService.copy(path, newName, targetDirectory, comment); } catch (Exception e) { throw ExceptionUtilities.handleException(e); } } @Override public List<Path> listDecisionTablesInPackage(final Path path) { try { final Package pkg = projectService.resolvePackage(path); if (pkg == null) { return Collections.emptyList(); } final Path pkgPath = pkg.getPackageMainResourcesPath(); final org.uberfire.java.nio.file.Path nioPkgPath = Paths.convert(pkgPath); final List<Path> paths = findDecisionTables(nioPkgPath); return paths; } catch (Exception e) { throw ExceptionUtilities.handleException(e); } } private List<Path> findDecisionTables(final org.uberfire.java.nio.file.Path nioRootPath) { final List<Path> paths = new ArrayList<>(); final DirectoryStream<org.uberfire.java.nio.file.Path> directoryStream = ioService.newDirectoryStream(nioRootPath); for (org.uberfire.java.nio.file.Path nioPath : directoryStream) { final Path path = Paths.convert(nioPath); if (!dotFileFilter.accept(nioPath) && resourceType.accept(path)) { paths.add(path); } } return paths; } private Set<Path> getLinkedDecisionTablesInPackage(final Path context) { final Set<Path> linkedDecisionTablePaths = new HashSet<>(); final List<Path> allDecisionTablePathsInPackage = listDecisionTablesInPackage(context); final List<Pair<Path, GuidedDecisionTable52>> allDecisionTablesInPackage = new ArrayList<>(); allDecisionTablePathsInPackage.forEach((path) -> allDecisionTablesInPackage.add(new Pair<>(path, dtableService.load(path)))); allDecisionTablesInPackage.forEach((source) -> { final List<Pair<Path, GuidedDecisionTable52>> otherDecisionTablesInPackage = new ArrayList<>(); otherDecisionTablesInPackage.addAll(allDecisionTablesInPackage); otherDecisionTablesInPackage.remove(source); otherDecisionTablesInPackage.forEach((target) -> dtableLinkManager.link(source.getK2(), target.getK2(), (s, t) -> { linkedDecisionTablePaths.add(source.getK1()); linkedDecisionTablePaths.add(target.getK1()); })); }); return linkedDecisionTablePaths; } }