Package org.drools.guvnor.server

Source Code of org.drools.guvnor.server.RepositoryAssetService

/*
* Copyright 2011 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.guvnor.server;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import org.drools.guvnor.client.rpc.AdminArchivedPageRow;
import org.drools.guvnor.client.rpc.AssetPageRequest;
import org.drools.guvnor.client.rpc.AssetPageRow;
import org.drools.guvnor.client.rpc.AssetService;
import org.drools.guvnor.client.rpc.BuilderResult;
import org.drools.guvnor.client.rpc.DetailedSerializationException;
import org.drools.guvnor.client.rpc.DiscussionRecord;
import org.drools.guvnor.client.rpc.PageRequest;
import org.drools.guvnor.client.rpc.PageResponse;
import org.drools.guvnor.client.rpc.PushResponse;
import org.drools.guvnor.client.rpc.QueryPageRequest;
import org.drools.guvnor.client.rpc.QueryPageRow;
import org.drools.guvnor.client.rpc.RuleAsset;
import org.drools.guvnor.client.rpc.TableDataResult;
import org.drools.guvnor.server.cache.RuleBaseCache;
import org.drools.guvnor.server.contenthandler.ContentHandler;
import org.drools.guvnor.server.contenthandler.ContentManager;
import org.drools.guvnor.server.contenthandler.ICanHasAttachment;
import org.drools.guvnor.server.repository.UserInbox;
import org.drools.guvnor.server.security.CategoryPathType;
import org.drools.guvnor.server.security.PackageNameType;
import org.drools.guvnor.server.security.RoleTypes;
import org.drools.guvnor.server.util.Discussion;
import org.drools.guvnor.server.util.LoggingHelper;
import org.drools.repository.AssetItem;
import org.drools.repository.PackageItem;
import org.drools.repository.RulesRepository;
import org.drools.repository.RulesRepositoryException;
import org.drools.repository.VersionableItem;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.remoting.WebRemote;
import org.jboss.seam.annotations.security.Restrict;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.security.Identity;

import com.google.gwt.user.client.rpc.SerializationException;

@Name("org.drools.guvnor.client.rpc.AssetService")
@AutoCreate
public class RepositoryAssetService
    implements
    AssetService {

    @In
    private RulesRepository            repository;

    private static final long          serialVersionUID          = 90111;

    private static final LoggingHelper log                       = LoggingHelper.getLogger( RepositoryAssetService.class );

    private final ServiceSecurity            serviceSecurity           = new ServiceSecurity();

    private final RepositoryAssetOperations  repositoryAssetOperations = new RepositoryAssetOperations();

    @Create
    public void create() {
        repositoryAssetOperations.setRulesRepository( getRulesRepository() );
    }

    /* This is called in hosted mode when creating "by hand" */
    public void setRulesRepository(RulesRepository repository) {
        this.repository = repository;
        create();
    }

    public RulesRepository getRulesRepository() {
        return repository;
    }

    /**
     * This actually does the hard work of loading up an asset based on its
     * format.
     *
     * Role-based Authorization check: This method can be accessed if user has
     * following permissions: 1. The user has a ANALYST_READ role or higher
     * (i.e., ANALYST) and this role has permission to access the category which
     * the asset belongs to. Or. 2. The user has a package.readonly role or
     * higher (i.e., package.admin, package.developer) and this role has
     * permission to access the package which the asset belongs to.
     */
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public RuleAsset loadRuleAsset(String uuid) throws SerializationException {

        long time = System.currentTimeMillis();

        AssetItem item = getRulesRepository().loadAssetByUUID( uuid );
        RuleAsset asset = new RuleAsset();

        asset.uuid = item.getUUID();
        asset.name = item.getName();
        asset.description = item.getDescription();
        asset.lastModified = item.getLastModified().getTime();
        asset.lastContributor = item.getLastContributor();
        asset.state = (item.getState() != null) ? item.getState().getName() : "";
        asset.dateCreated = item.getCreatedDate().getTime();
        asset.checkinComment = item.getCheckinComment();
        asset.versionNumber = item.getVersionNumber();

        // load standard meta data
        asset.metaData = repositoryAssetOperations.populateMetaData( item );

        // Verify if the user has permission to access the asset through package
        // based permission.
        // If failed, then verify if the user has permission to access the asset
        // through category
        // based permission
        if ( Contexts.isSessionContextActive() ) {

            try {
                Identity.instance().checkPermission( new PackageNameType( asset.metaData.packageName ),
                                                     RoleTypes.PACKAGE_READONLY );
            } catch ( RuntimeException e ) {
                handleLoadRuleAssetException( asset );
            }
        }

        PackageItem pkgItem = handlePackageItem( item,
                                                 asset );

        log.debug( "Package: " + pkgItem.getName() + ", asset: " + item.getName() + ". Load time taken for asset: " + (System.currentTimeMillis() - time) );
        UserInbox.recordOpeningEvent( item );
        return asset;

    }

    private PackageItem handlePackageItem(AssetItem item,
                                          RuleAsset asset) throws SerializationException {
        PackageItem pkgItem = item.getPackage();

        ContentHandler handler = ContentManager.getHandler( asset.metaData.format );
        handler.retrieveAssetContent( asset,
                                      item );

        asset.isreadonly = asset.metaData.hasSucceedingVersion;

        if ( pkgItem.isSnapshot() ) {
            asset.isreadonly = true;
        }
        return pkgItem;
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public RuleAsset[] loadRuleAssets(String[] uuids) throws SerializationException {
        return loadRuleAssets( Arrays.asList( uuids ) );
    }
   
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    /**
     *
     * Role-based Authorization check: This method can be accessed if user has
     * following permissions:
     * 1. The user has a Analyst role and this role has permission to access the category
     * which the asset belongs to.
     * Or.
     * 2. The user has a package.developer role or higher (i.e., package.admin)
     * and this role has permission to access the package which the asset belongs to.
     */
    public String checkinVersion(RuleAsset asset) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperOrAnalyst( asset );

        log.info( "USER:" + getCurrentUserName() + " CHECKING IN asset: [" + asset.name + "] UUID: [" + asset.uuid + "] " );
        return repositoryAssetOperations.checkinVersion( asset );      
    }
   
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void restoreVersion(String versionUUID,
                               String assetUUID,
                               String comment) {
        repositoryAssetOperations.restoreVersion( versionUUID, assetUUID, comment);
    }
   
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public TableDataResult loadItemHistory(String uuid) throws SerializationException {
        //VersionableItem assetItem = getRulesRepository().loadAssetByUUID( uuid );
        VersionableItem assetItem = getRulesRepository().loadItemByUUID( uuid );

        //serviceSecurity.checkSecurityAssetPackagePackageReadOnly( assetItem );
        return repositoryAssetOperations.loadItemHistory( assetItem );
    }

    /**
     * @deprecated in favour of {@link loadArchivedAssets(PageRequest)}
     */
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public TableDataResult loadAssetHistory(String packageUUID,
                                            String assetName) throws SerializationException {
        PackageItem pi = getRulesRepository().loadPackageByUUID( packageUUID );
        AssetItem assetItem = pi.loadAsset( assetName );
        serviceSecurity.checkSecurityIsPackageReadOnly( assetItem );

        return repositoryAssetOperations.loadItemHistory( assetItem );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    @Deprecated
    public TableDataResult loadArchivedAssets(int skip,
                                              int numRows) throws SerializationException {
        return repositoryAssetOperations.loadArchivedAssets( skip,
                                                             numRows );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public PageResponse<AdminArchivedPageRow> loadArchivedAssets(PageRequest request) throws SerializationException {
        if ( request == null ) {
            throw new IllegalArgumentException( "request cannot be null" );
        }
        if ( request.getPageSize() != null && request.getPageSize() < 0 ) {
            throw new IllegalArgumentException( "pageSize cannot be less than zero." );
        }

        return repositoryAssetOperations.loadArchivedAssets( request );
    }

    /**
     * @deprecated in favour of {@link findAssetPage(AssetPageRequest)}
     */
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public TableDataResult listAssetsWithPackageName(String packageName,
                                                     String formats[],
                                                     int skip,
                                                     int numRows,
                                                     String tableConfig) throws SerializationException {
        PackageItem pkg = getRulesRepository().loadPackage( packageName );
        return listAssets( pkg.getUUID(),
                           formats,
                           skip,
                           numRows,
                           tableConfig );
    }

    /**
     * @deprecated in favour of {@link findAssetPage(AssetPageRequest)}
     */
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public TableDataResult listAssets(String packageUuid,
                                      String formats[],
                                      int skip,
                                      int numRows,
                                      String tableConfig) throws SerializationException {
        log.debug( "Loading asset list for [" + packageUuid + "]" );
        if ( numRows == 0 ) {
            throw new DetailedSerializationException( "Unable to return zero results (bug)",
                                                      "probably have the parameters around the wrong way, sigh..." );
        }
        return repositoryAssetOperations.listAssets( packageUuid,
                                                     formats,
                                                     skip,
                                                     numRows,
                                                     tableConfig );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public String copyAsset(String assetUUID,
                            String newPackage,
                            String newName) {
        serviceSecurity.checkIsPackageDeveloper( newPackage );

        log.info( "USER:" + getCurrentUserName() + " COPYING asset: [" + assetUUID + "] to [" + newName + "] in PACKAGE [" + newPackage + "]" );
        return getRulesRepository().copyAsset( assetUUID,
                                               newPackage,
                                               newName );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void changeAssetPackage(String uuid,
                                   String newPackage,
                                   String comment) {
        serviceSecurity.checkIsPackageDeveloper( newPackage );

        log.info( "USER:" + getCurrentUserName() + " CHANGING PACKAGE OF asset: [" + uuid + "] to [" + newPackage + "]" );
        getRulesRepository().moveRuleItemPackage( newPackage,
                                                  uuid,
                                                  comment );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void promoteAssetToGlobalArea(String uuid) {
        serviceSecurity.checkIsPackageDeveloper( RulesRepository.RULE_GLOBAL_AREA );
        AssetItem item = getRulesRepository().loadAssetByUUID( uuid );
        //serviceSecurity.checkIsPackageDeveloper( item );
       
        log.info( "USER:" + getCurrentUserName() + " CHANGING PACKAGE OF asset: [" + uuid + "] to [ globalArea ]" );
        getRulesRepository().moveRuleItemPackage( RulesRepository.RULE_GLOBAL_AREA,
                                                  uuid,
                                                  "promote asset to globalArea" );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public String buildAssetSource(RuleAsset asset) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperOrAnalyst(asset);
        return repositoryAssetOperations.buildAssetSource( asset );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public String renameAsset(String uuid,
                              String newName) {
        AssetItem item = getRulesRepository().loadAssetByUUID( uuid );
        serviceSecurity.checkSecurityIsPackageDeveloperOrAnalyst( item );

        return repositoryAssetOperations.renameAsset( uuid,
                                                      newName );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void archiveAsset(String uuid) {
        archiveOrUnarchiveAsset( uuid,
                                 true );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public BuilderResult validateAsset(RuleAsset asset) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperOrAnalyst( asset );
        return repositoryAssetOperations.validateAsset(asset);
    }

    public void unArchiveAsset(String uuid) {
        archiveOrUnarchiveAsset( uuid,
                                 false );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void archiveAssets(String[] uuids,
                              boolean value) {
        for ( String uuid : uuids ) {
            archiveOrUnarchiveAsset( uuid,
                                     value );
        }
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void removeAsset(String uuid) {
        try {
            AssetItem item = getRulesRepository().loadAssetByUUID( uuid );
            serviceSecurity.checkSecurityIsPackageDeveloper( item );

            item.remove();
            getRulesRepository().save();
        } catch ( RulesRepositoryException e ) {
            log.error( "Unable to remove asset.",
                       e );
            throw e;
        }
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void removeAssets(String[] uuids) {
        for ( String uuid : uuids ) {
            removeAsset( uuid );
        }
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public PageResponse<AssetPageRow> findAssetPage(AssetPageRequest request) throws SerializationException {
        if ( request == null ) {
            throw new IllegalArgumentException( "request cannot be null" );
        }
        if ( request.getPageSize() != null && request.getPageSize() < 0 ) {
            throw new IllegalArgumentException( "pageSize cannot be less than zero." );
        }

        return repositoryAssetOperations.findAssetPage( request );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public PageResponse<QueryPageRow> quickFindAsset(QueryPageRequest request) throws SerializationException {
        if ( request == null ) {
            throw new IllegalArgumentException( "request cannot be null" );
        }
        if ( request.getPageSize() != null && request.getPageSize() < 0 ) {
            throw new IllegalArgumentException( "pageSize cannot be less than zero." );
        }

        return repositoryAssetOperations.quickFindAsset( request );
    }

    /**
     * @deprecated in favour of {@link quickFindAsset(QueryPageRequest)}
     */
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public TableDataResult quickFindAsset(String searchText,
                                          boolean searchArchived,
                                          int skip,
                                          int numRows) throws SerializationException {
        return repositoryAssetOperations.quickFindAsset( searchText,
                                                         searchArchived,
                                                         skip,
                                                         numRows );
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.drools.guvnor.client.rpc.RepositoryService#lockAsset(java.lang.String
     * )
     */
    @Restrict("#{identity.loggedIn}")
    public void lockAsset(String uuid) {
        repositoryAssetOperations.lockAsset( uuid );
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.drools.guvnor.client.rpc.RepositoryService#unLockAsset(java.lang.
     * String)
     */
    @Restrict("#{identity.loggedIn}")
    public void unLockAsset(String uuid) {
        repositoryAssetOperations.unLockAsset( uuid );
    }

    /**
     * @deprecated in favour of {@link queryFullText(QueryPageRequest)}
     */
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public TableDataResult queryFullText(String text,
                                         boolean seekArchived,
                                         int skip,
                                         int numRows) throws SerializationException {
        if ( numRows == 0 ) {
            throw new DetailedSerializationException( "Unable to return zero results (bug)",
                                                      "probably have the parameters around the wrong way, sigh..." );
        }
        return repositoryAssetOperations.queryFullText( text,
                                                        seekArchived,
                                                        skip,
                                                        numRows );
    }

    private void handleLoadRuleAssetException(RuleAsset asset) {
        if ( asset.metaData.categories.length == 0 ) {
            Identity.instance().checkPermission( new CategoryPathType( null ),
                                                 RoleTypes.ANALYST_READ );
        } else {
            RuntimeException exception = null;
            boolean passed = false;
            for ( String cat : asset.metaData.categories ) {
                try {
                    Identity.instance().checkPermission( new CategoryPathType( cat ),
                                                         RoleTypes.ANALYST_READ );
                    passed = true;
                } catch ( RuntimeException re ) {
                    exception = re;
                }
            }
            if ( !passed ) {
                throw exception;
            }
        }
    }

    RuleAsset[] loadRuleAssets(Collection<String> uuids) throws SerializationException {
        if ( uuids == null ) {
            return null;
        }
        Collection<RuleAsset> assets = new HashSet<RuleAsset>();

        for ( String uuid : uuids ) {
            assets.add( loadRuleAsset( uuid ) );
        }

        return assets.toArray( new RuleAsset[assets.size()] );
    }

    private void archiveOrUnarchiveAsset(String uuid,
                                         boolean archive) {
        try {
            AssetItem item = getRulesRepository().loadAssetByUUID( uuid );

            serviceSecurity.checkSecurityIsPackageDeveloperOrAnalyst( item );

            if ( item.getPackage().isArchived() ) {
                throw new RulesRepositoryException( "The package [" + item.getPackageName() + "] that asset [" + item.getName() + "] belongs to is archived. You need to unarchive it first." );
            }

            log.info( "USER:" + getCurrentUserName() + " ARCHIVING asset: [" + item.getName() + "] UUID: [" + item.getUUID() + "] " );

            try {
                ContentHandler handler = getContentHandler( item );
                if ( handler instanceof ICanHasAttachment ) {
                    ((ICanHasAttachment) handler).onAttachmentRemoved( item );
                }
            } catch ( IOException e ) {
                log.error( "Unable to remove asset attachment",
                           e );
            }

            item.archiveItem( archive );
            PackageItem pkg = item.getPackage();
            pkg.updateBinaryUpToDate( false );
            RuleBaseCache.getInstance().remove( pkg.getUUID() );
            if ( archive ) {
                item.checkin( "archived" );
            } else {
                item.checkin( "unarchived" );
            }

            push( "packageChange",
                  pkg.getName() );

        } catch ( RulesRepositoryException e ) {
            log.error( "Unable to get item format.",
                       e );
            throw e;
        }
    }

    @Restrict("#{identity.loggedIn}")
    public List<DiscussionRecord> addToDiscussionForAsset(String assetId,
                                                          String comment) {
        return repositoryAssetOperations.addToDiscussionForAsset( assetId,
                                                                  comment );
    }

    @Restrict("#{identity.loggedIn}")
    public void clearAllDiscussionsForAsset(final String assetId) {
        serviceSecurity.checkSecurityIsAdmin();
        repositoryAssetOperations.clearAllDiscussionsForAsset( assetId );
    }

    @Restrict("#{identity.loggedIn}")
    public List<DiscussionRecord> loadDiscussionForAsset(String assetId) {
        return new Discussion().fromString( getRulesRepository().loadAssetByUUID( assetId ).getStringProperty( Discussion.DISCUSSION_PROPERTY_KEY ) );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void changeState(String uuid,
                            String newState) {
        AssetItem asset = getRulesRepository().loadAssetByUUID( uuid );
        serviceSecurity.checkSecurityIsPackageDeveloperOrAnalyst( asset );

        log.info( "USER:" + getCurrentUserName() + " CHANGING ASSET STATUS. Asset name, uuid: " + "[" + asset.getName() + ", " + asset.getUUID() + "]" + " to [" + newState + "]" );
        String oldState = asset.getStateDescription();
        asset.updateState( newState );

        push( "statusChange",
                  oldState );
        push( "statusChange",
                  newState );

        addToDiscussionForAsset( asset.getUUID(),
                                     oldState + " -> " + newState );

        getRulesRepository().save();
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void changePackageState(String uuid,
                                   String newState) {

        serviceSecurity.checkSecurityIsPackageDeveloper( uuid );

        PackageItem pkg = getRulesRepository().loadPackageByUUID( uuid );
        log.info( "USER:" + getCurrentUserName() + " CHANGING Package STATUS. Asset name, uuid: " + "[" + pkg.getName() + ", " + pkg.getUUID() + "]" + " to [" + newState + "]" );
        pkg.changeStatus( newState );

        getRulesRepository().save();
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.drools.guvnor.client.rpc.RepositoryService#getAssetLockerUserName
     * (java.lang.String)
     */
    @Restrict("#{identity.loggedIn}")
    public String getAssetLockerUserName(String uuid) {
        return repositoryAssetOperations.getAssetLockerUserName( uuid );
    }

    private void push(String messageType,
                      String message) {
        Backchannel.getInstance().publish( new PushResponse( messageType,
                                                             message ) );
    }

    private ContentHandler getContentHandler(AssetItem repoAsset) {
        return ContentManager.getHandler( repoAsset.getFormat() );
    }

    private String getCurrentUserName() {
        return getRulesRepository().getSession().getUserID();
    }

}
TOP

Related Classes of org.drools.guvnor.server.RepositoryAssetService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.