Subversion Repositories XServices

Rev

Rev 175 | Blame | Last modification | View Log | Download | RSS feed

/*
 *   Copyright 2014 Brian Rosenberger (Brutex Network)
 *
 *   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 net.brutex.xservices.ws.rs;



import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.fluent.Configurations;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.jcs.JCS;
import org.apache.commons.jcs.access.CacheAccess;
import org.apache.commons.jcs.access.exception.CacheException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import net.brutex.xservices.cmtypes.ItemType;
import net.brutex.xservices.cmtypes.ItemTypeList;
import net.brutex.xservices.types.FileInfoType;
import net.brutex.xservices.util.FileWalker;



/*
 * The Serena Dimensions CM Java API is required for these imports.
 * The API is not included in this package due to copyright reasons,
 * please get Dimensions CM from Serena Software Inc., Evaluation versions
 * are available from http://www.serena.com
 * 
 * required Jars:
 * serena.darius-14.1.jar
 * serena.dmclient-14.1.jar
 * serena.dmfile-14.1.jar
 * serena.dmnet-14.1.jar
 * serena.dmtpi-14.1.jar
 * 
 */

import com.serena.dmclient.api.BulkOperator;
import com.serena.dmclient.api.DimensionsConnection;
import com.serena.dmclient.api.DimensionsConnectionDetails;
import com.serena.dmclient.api.DimensionsConnectionManager;
import com.serena.dmclient.api.ItemRevision;
import com.serena.dmclient.api.Project;
import com.serena.dmclient.api.RepositoryFolder;
import com.serena.dmclient.api.SystemAttributes;

/**
 * The Class FileInfoImpl.
 * 
 * @author Brian Rosenberger, bru(at)brutex.de
 */
public class DIMCMInfoImpl implements DIMCMInfo {

        Logger logger = LogManager.getLogger();

        /*
         * (non-Javadoc)
         * 
         * @see
         * net.brutex.xservices.ws.rs.FileInfo#getFiles(javax.ws.rs.core.HttpHeaders
         * , java.lang.String, boolean, boolean, int, java.lang.String, int, int)
         */
        public Response getFiles(HttpHeaders h, UriInfo uriInfo, String projSpec,
                        String directory, boolean recursive, boolean withFiles, int level,
                        String search, int count, int page, boolean useCache) throws CacheException {

                
                /*
                 * try to hit cache first
                 */
                CacheAccess<Object, Object> cache = JCS.getInstance("DIMCM");
                String cachekey = projSpec + directory + String.valueOf(recursive);
                if(useCache) {
                                ItemTypeList cacheresult = (ItemTypeList) cache.get(cachekey);
                                if(cacheresult != null) return Response.ok(cacheresult).build();
                }
                
                //Reject when project has not the form "PRODUCT:PROJECT"
                if(! projSpec.contains(":")) return Response.noContent().build();
                
                Project project = getDIMCMConnection().getObjectFactory().getProject(projSpec);
                RepositoryFolder folder = null;
                
                if (directory == null) {
                        folder = project.getRootFolder();
                } else {
                        while(directory.startsWith("/") || directory.startsWith("\\")) {
                                directory = directory.substring(1);
                        }
                        if(directory.equals("")) {
                                folder = project.getRootFolder();
                        } else {
                                folder = project.findRepositoryFolderByPath(directory);
                        }
                }

                
                ItemTypeList resultlist = new ItemTypeList();
                resultlist.list = getItems(folder, recursive);
                if(cache!=null) cache.put(cachekey, resultlist);
                
                //does this help?
                DimensionsConnectionManager.unregisterThreadConnection();
                
                return Response.ok(resultlist).build();

        }

        
        
        
        List<ItemType> getItems(RepositoryFolder f, boolean recursive) {
                DimensionsConnection conn = getDIMCMConnection();
                List<ItemType> result = new ArrayList<>();

                /* get Items from current folder */
                /* latest revision only */
                List<ItemRevision> revisions = f.getLatestItemRevisions();

                int[] attr = { SystemAttributes.FULL_PATH_NAME,
                                SystemAttributes.ITEMFILE_DIR,
                                SystemAttributes.ITEMFILE_FILENAME,
                                SystemAttributes.ITEMFILE_DIR, SystemAttributes.OBJECT_SPEC,
                                SystemAttributes.OBJECT_ID, SystemAttributes.OBJECT_SPEC_UID,
                                SystemAttributes.OBJECT_UID, SystemAttributes.CREATION_DATE,
                                SystemAttributes.CREATION_USER, SystemAttributes.ITEM_FORMAT,
                                SystemAttributes.LAST_UPDATED_DATE,
                                SystemAttributes.LAST_UPDATED_USER };
                BulkOperator bulk = conn.getObjectFactory().getBulkOperator(revisions);
                bulk.queryAttribute(attr);

                // Copy into JAXB object
                for (ItemRevision r : revisions) {
                        ItemType item = new ItemType();
                        item.setLongFilename((String) r
                                        .getAttribute(SystemAttributes.FULL_PATH_NAME));
                        item.setDirName((String) r
                                        .getAttribute(SystemAttributes.ITEMFILE_DIR));
                        item.setShortFilename((String) r
                                        .getAttribute(SystemAttributes.ITEMFILE_FILENAME));
                        item.setObject_id((String) r
                                        .getAttribute(SystemAttributes.OBJECT_ID));
                        item.setObject_uid((String.valueOf(r
                                        .getAttribute(SystemAttributes.OBJECT_UID))));
                        item.setObject_spec((String) r
                                        .getAttribute(SystemAttributes.OBJECT_SPEC));
                        item.setObject_spec_uid(String.valueOf(r
                                        .getAttribute(SystemAttributes.OBJECT_SPEC_UID)));
                        item.setObject_spec_uid(String.valueOf(r
                                        .getAttribute(SystemAttributes.OBJECT_SPEC_UID)));
                        item.setCreatedDate(String.valueOf(r
                                        .getAttribute(SystemAttributes.CREATION_DATE)));
                        item.setCreatedUser(String.valueOf(r
                                        .getAttribute(SystemAttributes.CREATION_USER)));
                        item.setItemFormat(String.valueOf(r
                                        .getAttribute(SystemAttributes.ITEM_FORMAT)));
                        item.setUpdatedDate(String.valueOf(r
                                        .getAttribute(SystemAttributes.LAST_UPDATED_DATE)));
                        item.setUpdatedUser(String.valueOf(r
                                        .getAttribute(SystemAttributes.LAST_UPDATED_USER)));

                        try {
                                item.setUrl(new URL(getBaseURL()
                                                + "?jsp=api&command=openi&object_id="
                                                + item.getObject_spec() + "&DB_CONN="
                                                + conn.getConnectionDetails().getDbConn() + "&DB_NAME="
                                                + conn.getConnectionDetails().getDbName()));
                        } catch (MalformedURLException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                        result.add(item);
                }
                
                /*
                 * for recursive add other folders
                 */
                if(recursive) {
                        List<RepositoryFolder> folders = f.getAllChildFolders();
                        for(RepositoryFolder ff : folders) {
                                result.addAll(getItems(ff, false));
                        }
                }
                
                return result;
        }

        /**
         * Sets the directory.
         * 
         * @param list
         *            the list
         * @param dir
         *            the dir
         * @param withDirectories
         *            the with directories
         * @param withFiles
         *            the with files
         * @param depth
         *            the depth
         * @param search
         *            the search
         */
        private void setDirectory(final URI baseuri, final List<FileInfoType> list,
                        File dir, boolean withDirectories, boolean withFiles,
                        final int depth, String search) {
                if (depth <= 0)
                        return;

                if (search == null || search.equals("")) {
                        search = "*";
                        logger.info("No search pattern supplied, using default '*'.");
                }

                FileWalker finder = new FileWalker(search);
                try {
                        Files.walkFileTree(dir.toPath(),
                                        EnumSet.of(FileVisitOption.FOLLOW_LINKS), depth, finder);
                        logger.info("FileWalker returned '" + finder.getCount()
                                        + "' hits. '" + finder.getTotal()
                                        + "' files have been scanned.");
                        List<Path> result = finder.getResult();
                        for (Path f : result) {
                                if (!withDirectories) {
                                        if (f.toFile().isDirectory())
                                                continue;
                                }
                                if (!withFiles) {
                                        if (f.toFile().isFile())
                                                continue;
                                }
                                list.add(new FileInfoType(f, baseuri));
                        }
                } catch (IOException e2) {
                        logger.error(e2.getMessage(), e2);
                        ;
                }
        }

        /**
         * Sets the directory.
         * 
         * @param dir
         *            the dir
         * @param withDirectories
         *            the with directories
         * @param withFiles
         *            the with files
         * @param depth
         *            the depth
         * @param search
         *            the search
         * @return the list
         */
        private List<FileInfoType> setDirectory(URI baseuri, String dir,
                        boolean withDirectories, boolean withFiles, int depth, String search) {
                List<FileInfoType> list = new ArrayList<FileInfoType>();
                setDirectory(baseuri, list, new File(dir), withDirectories, withFiles,
                                depth, search);
                return list;
        }

        private boolean isPermitted(String dir) {
                /*
                 * 
                 * logger.warn(String.format(
                 * "User '%s' does not have permission to access '%s'."
                 * ,SecurityUtils.getSubject().getPrincipal(), dir )); throw new
                 * NotAuthorizedException(new
                 * UnauthorizedException("User does not have permission to access "+
                 * dir)); }
                 */
                return true;
        }

        // http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
        private static String humanReadableByteCount(long bytes, boolean si) {
                int unit = si ? 1000 : 1024;
                if (bytes < unit)
                        return bytes + " B";
                int exp = (int) (Math.log(bytes) / Math.log(unit));
                String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1)
                                + (si ? "" : "i");
                return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
        }

        private DimensionsConnection getDIMCMConnection() {
                /*
                 * Do we have a registered connection already?
                 */
                DimensionsConnection conn = null;
                
                try {
                        conn = DimensionsConnectionManager.getThreadConnection();
                        if (conn != null)
                                return conn;
                } catch (Exception e) {
                        logger.error(e.getMessage());
                }

                /*
                 * Create a new connection from property file
                 */
                PropertiesConfiguration props;
                try {
                        
                        props = new Configurations().properties(this.getClass()
                                        .getClassLoader().getResource("/../dimcm.properties"));
                } catch (ConfigurationException e) {
                        e.printStackTrace();
                        return null;
                }

                DimensionsConnectionDetails details = new DimensionsConnectionDetails();
                details.setUsername(props.getString("user"));
                details.setPassword(props.getString("password"));
                details.setDbName(props.getString("dbname"));
                details.setDbConn(props.getString("dbconn"));
                details.setServer(props.getString("server"));
                conn = DimensionsConnectionManager.getConnection(details);
                DimensionsConnectionManager.registerThreadConnection(conn);
                return conn;
        }

        private String getBaseURL() {
                final String CACHE_BASEURL = "DIMCM.conf.baseurl";
        try {
                CacheAccess<Object, Object> cache = JCS.getInstance("DIMCM");
                String baseurl = (String) cache.get(CACHE_BASEURL);
                if(baseurl != null) return baseurl;
                
                Configurations configs = new Configurations();
                
                PropertiesConfiguration props = configs.properties((this.getClass().getClassLoader().getResource("/../dimcm.properties")));
                baseurl = props.getString("baseurl");
                cache.put(CACHE_BASEURL, baseurl);
                return baseurl;
                
        } catch (CacheException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                return null;
        } catch (ConfigurationException e) {
                e.printStackTrace();
                return null;
                
        }
}
}

Generated by GNU Enscript 1.6.5.90.