0,0 → 1,371 |
/* |
* 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 net.brutex.xservices.cmtypes.ItemType; |
import net.brutex.xservices.cmtypes.ItemTypeList; |
import net.brutex.xservices.types.FileInfoType; |
import net.brutex.xservices.util.FileWalker; |
|
import org.apache.commons.configuration.ConfigurationException; |
import org.apache.commons.configuration.PropertiesConfiguration; |
import org.apache.jcs.JCS; |
import org.apache.jcs.access.exception.CacheException; |
import org.apache.log4j.Logger; |
|
|
/* |
* 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 = Logger.getLogger(DIMCMInfoImpl.class); |
|
/* |
* (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 |
*/ |
JCS 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 PropertiesConfiguration(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 { |
JCS cache = JCS.getInstance("DIMCM"); |
String baseurl = (String) cache.get(CACHE_BASEURL); |
if(baseurl != null) return baseurl; |
|
PropertiesConfiguration props = new PropertiesConfiguration(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; |
|
} |
} |
} |
Property changes: |
Added: svn:mime-type |
+text/plain |
\ No newline at end of property |