Java tutorial
/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * * Copyright 2006 - 2013 Pentaho Corporation. All rights reserved. */ package org.pentaho.platform.repository2.unified.fs; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; import org.apache.commons.lang.StringUtils; import org.pentaho.platform.api.locale.IPentahoLocale; import org.pentaho.platform.api.repository2.unified.IRepositoryFileData; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.RepositoryFileAcl; import org.pentaho.platform.api.repository2.unified.RepositoryFileTree; import org.pentaho.platform.api.repository2.unified.RepositoryRequest; import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; import org.pentaho.platform.api.repository2.unified.VersionSummary; import org.pentaho.platform.api.repository2.unified.data.node.NodeRepositoryFileData; import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData; import org.pentaho.platform.repository.RepositoryFilenameUtils; import org.pentaho.platform.repository2.unified.IRepositoryFileDao; import org.pentaho.platform.util.RepositoryPathEncoder; @SuppressWarnings("nls") public class FileSystemRepositoryFileDao implements IRepositoryFileDao { private File rootDir = new File(System.getProperty("solution.root.dir", System.getProperty("user.dir"))); private static List<Character> reservedChars = Collections .unmodifiableList(Arrays.asList(new Character[] { '/', '\\', '\t', '\r', '\n' })); private static List<Character> reservedCharsWindows = Collections .unmodifiableList(Arrays.asList(new Character[] { '?', '*', ':', '<', '>', '|' })); public FileSystemRepositoryFileDao() { this(new File(System.getProperty("solution.root.dir", System.getProperty("user.dir")))); } public FileSystemRepositoryFileDao(final String baseDir) { this(new File(baseDir)); } public FileSystemRepositoryFileDao(File baseDir) { // Detect OS final String os = System.getProperty("os.name").toLowerCase(); if (os.contains("win") && baseDir.getPath().equals("\\")) { baseDir = new File("C:\\"); } assert (baseDir.exists() && baseDir.isDirectory()); this.rootDir = baseDir; } public boolean canUnlockFile(Serializable fileId) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public File getRootDir() { return new File(rootDir.getAbsolutePath()); } private byte[] inputStreamToBytes(InputStream in) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(4096); byte[] buffer = new byte[4096]; int len; while ((len = in.read(buffer)) >= 0) { out.write(buffer, 0, len); } in.close(); out.close(); return out.toByteArray(); } public RepositoryFile createFile(Serializable parentFolderId, RepositoryFile file, IRepositoryFileData data, RepositoryFileAcl acl, String versionMessage) { String fileNameWithPath = RepositoryFilenameUtils.concat(parentFolderId.toString(), file.getName()); FileOutputStream fos = null; File f = new File(fileNameWithPath); try { f.createNewFile(); fos = new FileOutputStream(f); if (data instanceof SimpleRepositoryFileData) { fos.write(inputStreamToBytes(((SimpleRepositoryFileData) data).getInputStream())); } else if (data instanceof NodeRepositoryFileData) { fos.write(inputStreamToBytes( new ByteArrayInputStream(((NodeRepositoryFileData) data).getNode().toString().getBytes()))); } } catch (FileNotFoundException e) { throw new UnifiedRepositoryException("Error writing file [" + fileNameWithPath + "]", e); } catch (IOException e) { throw new UnifiedRepositoryException("Error writing file [" + fileNameWithPath + "]", e); } finally { IOUtils.closeQuietly(fos); } return internalGetFile(f); } public RepositoryFile createFolder(Serializable parentFolderId, RepositoryFile file, RepositoryFileAcl acl, String versionMessage) { try { String folderNameWithPath = parentFolderId + "/" + file.getName(); File newFolder = new File(folderNameWithPath); newFolder.mkdir(); final RepositoryFile repositoryFolder = internalGetFile(newFolder); return repositoryFolder; } catch (Throwable th) { throw new UnifiedRepositoryException(); } } public void deleteFile(Serializable fileId, String versionMessage) { try { File f = new File(fileId.toString()); f.delete(); } catch (Exception e) { // CHECKSTYLES IGNORE } } public void deleteFileAtVersion(Serializable fileId, Serializable versionId) { deleteFile(fileId, null); } @Override public List<RepositoryFile> getChildren(RepositoryRequest repositoryRequest) { List<RepositoryFile> children = new ArrayList<RepositoryFile>(); File folder = new File(getPhysicalFileLocation(repositoryRequest.getPath())); for (Iterator<File> iterator = FileUtils .listFiles(folder, new WildcardFileFilter(repositoryRequest.getChildNodeFilter()), null) .iterator(); iterator.hasNext();) { children.add(internalGetFile((File) iterator.next())); } return children; } @Deprecated public List<RepositoryFile> getChildren(Serializable folderId) { return getChildren(folderId, "", false); } @Deprecated public List<RepositoryFile> getChildren(Serializable folderId, String filter) { return getChildren(folderId, filter, false); } @Deprecated public List<RepositoryFile> getChildren(Serializable folderId, String filter, Boolean showHiddenFiles) { return getChildren(new RepositoryRequest(folderId.toString(), showHiddenFiles, -1, filter)); } @SuppressWarnings("unchecked") public <T extends IRepositoryFileData> T getData(Serializable fileId, Serializable versionId, Class<T> dataClass) { File f = new File(fileId.toString()); T data = null; try { if (SimpleRepositoryFileData.class.getName().equals(dataClass.getName())) { data = (T) new SimpleRepositoryFileData(new FileInputStream(f), "UTF-8", "text/plain"); } else if (NodeRepositoryFileData.class.getName().equals(dataClass.getName())) { throw new UnsupportedOperationException("This operation is not support by this repository"); } } catch (FileNotFoundException e) { throw new UnifiedRepositoryException(e); } return data; } public List<RepositoryFile> getDeletedFiles(Serializable folderId, String filter) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public List<RepositoryFile> getDeletedFiles() { throw new UnsupportedOperationException("This operation is not support by this repository"); } public RepositoryFile internalGetFile(File f) { RepositoryFile file = null; if (f.exists()) { String jcrPath = f.getAbsolutePath().substring(rootDir.getAbsolutePath().length()); if (jcrPath.length() == 0) { jcrPath = "/"; } file = new RepositoryFile.Builder(f.getAbsolutePath(), f.getName()) .createdDate(new Date(f.lastModified())).lastModificationDate(new Date(f.lastModified())) .folder(f.isDirectory()).versioned(false).path(jcrPath).versionId(f.getName()).locked(false) .lockDate(null).lockMessage(null).lockOwner(null).title(f.getName()).description(f.getName()) .locale(null).fileSize(f.length()).build(); } return file; } public RepositoryFile getFile(String relPath) { return internalGetFile(new File(getPhysicalFileLocation(relPath))); } static String idToPath(String relPath) { relPath = RepositoryPathEncoder.decodeRepositoryPath(relPath); return relPath.replaceFirst("^/?([A-z])/[/\\\\](.*)", "$1:/$2"); } public RepositoryFile getFile(Serializable fileId, Serializable versionId) { return getFile(fileId.toString()); } public RepositoryFile getFileByAbsolutePath(String absPath) { return getFile(absPath); } public RepositoryFile getFileById(Serializable fileId) { return getFile(fileId.toString()); } public RepositoryFile getFile(String relPath, boolean loadLocaleMaps) { return getFile(relPath); } public RepositoryFile getFileById(Serializable fileId, boolean loadLocaleMaps) { return getFile(fileId.toString()); } @Override public RepositoryFile getFile(String relPath, IPentahoLocale locale) { return getFile(relPath); } @Override public RepositoryFile getFileById(Serializable fileId, IPentahoLocale locale) { return getFile(fileId.toString()); } @Override public RepositoryFile getFile(String relPath, boolean loadLocaleMaps, IPentahoLocale locale) { return getFile(relPath); } @Override public RepositoryFile getFileById(Serializable fileId, boolean loadLocaleMaps, IPentahoLocale locale) { return getFile(fileId.toString()); } @Override public RepositoryFileTree getTree(RepositoryRequest repositoryRequest) { File root = new File(getPhysicalFileLocation(repositoryRequest.getPath())); //TODO ACL return getTree(root, repositoryRequest.getDepth().intValue(), repositoryRequest.getChildNodeFilter(), repositoryRequest.getTypes()); } @Deprecated public RepositoryFileTree getTree(String relPath, int depth, String filter, boolean showHidden) { File root = new File(getPhysicalFileLocation(relPath)); //TODO ACL return getTree(root, depth, filter, RepositoryRequest.FILES_TYPE_FILTER.FILES_FOLDERS); } private RepositoryFileTree getTree(final File file, final int depth, final String childNodeFilter, RepositoryRequest.FILES_TYPE_FILTER types) { RepositoryFile rootFile = internalGetFile(file); List<RepositoryFileTree> children; if (depth != 0) { children = new ArrayList<RepositoryFileTree>(); if (file.isDirectory()) { File[] childrenArray = file.listFiles(); for (File child : childrenArray) { if (child.isFile()) { if (types == RepositoryRequest.FILES_TYPE_FILTER.FILES_FOLDERS || types == RepositoryRequest.FILES_TYPE_FILTER.FILES) { children.add(new RepositoryFileTree(internalGetFile(child), new ArrayList<RepositoryFileTree>())); } continue; } RepositoryFileTree repositoryChildFileTree = getTree(child, depth - 1, childNodeFilter, types); if (repositoryChildFileTree != null) { children.add(repositoryChildFileTree); } } } Collections.sort(children); } else { children = null; } return new RepositoryFileTree(rootFile, children); } public List<VersionSummary> getVersionSummaries(Serializable fileId) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public VersionSummary getVersionSummary(Serializable fileId, Serializable versionId) { RepositoryFile file = getFile(fileId, versionId); List<String> labels = new ArrayList<String>(); return new VersionSummary(fileId, (versionId != null ? versionId : fileId), false, file.getCreatedDate(), file.getCreatorId(), StringUtils.EMPTY, labels); } public void lockFile(Serializable fileId, String message) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public void moveFile(Serializable fileId, String destRelPath, String versionMessage) { RepositoryFile file = getFileById(fileId); SimpleRepositoryFileData data = getData(fileId, null, SimpleRepositoryFileData.class); deleteFile(fileId, versionMessage); createFile(null, file, data, null, versionMessage); } public void permanentlyDeleteFile(Serializable fileId, String versionMessage) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public void restoreFileAtVersion(Serializable fileId, Serializable versionId, String versionMessage) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public void undeleteFile(Serializable fileId, String versionMessage) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public void unlockFile(Serializable fileId) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public RepositoryFile updateFile(RepositoryFile file, IRepositoryFileData data, String versionMessage) { File f = new File(file.getId().toString()); FileOutputStream fos = null; try { fos = new FileOutputStream(f, false); if (data instanceof SimpleRepositoryFileData) { fos.write(inputStreamToBytes(((SimpleRepositoryFileData) data).getInputStream())); } else if (data instanceof NodeRepositoryFileData) { fos.write(inputStreamToBytes( new ByteArrayInputStream(((NodeRepositoryFileData) data).getNode().toString().getBytes()))); } } catch (FileNotFoundException e) { throw new UnifiedRepositoryException(e); } catch (IOException e) { throw new UnifiedRepositoryException(e); } finally { IOUtils.closeQuietly(fos); } return getFile(file.getPath()); } public List<RepositoryFile> getReferrers(Serializable fileId) { throw new UnsupportedOperationException(); } public void setRootDir(File rootDir) { this.rootDir = rootDir; } public void setFileMetadata(final Serializable fileId, Map<String, Serializable> metadataMap) { final File targetFile = new File(fileId.toString()); if (targetFile.exists()) { FileOutputStream fos = null; try { final File metadataDir = new File(targetFile.getParent() + File.separatorChar + ".metadata"); if (!metadataDir.exists()) { metadataDir.mkdir(); } final File metadataFile = new File(metadataDir, targetFile.getName()); if (!metadataFile.exists()) { metadataFile.createNewFile(); } final StringBuilder data = new StringBuilder(); for (String key : metadataMap.keySet()) { data.append(key).append('='); if (metadataMap.get(key) != null) { data.append(metadataMap.get(key).toString()); } data.append('\n'); } fos = new FileOutputStream(metadataFile); fos.write(data.toString().getBytes()); } catch (FileNotFoundException e) { throw new UnifiedRepositoryException("Error writing file metadata [" + fileId + "]", e); } catch (IOException e) { throw new UnifiedRepositoryException("Error writing file metadata [" + fileId + "]", e); } finally { IOUtils.closeQuietly(fos); } } } public Map<String, Serializable> getFileMetadata(final Serializable fileId) { final String metadataFilename = FilenameUtils.concat( FilenameUtils.concat(FilenameUtils.getFullPathNoEndSeparator(fileId.toString()), ".metadata"), FilenameUtils.getName(fileId.toString())); final Map<String, Serializable> metadata = new HashMap<String, Serializable>(); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(metadataFilename)); String data = reader.readLine(); while (data != null) { final int pos = data.indexOf('='); if (pos > 0) { final String key = data.substring(0, pos); final String value = (data.length() > pos ? data.substring(pos + 1) : null); metadata.put(key, value); } data = reader.readLine(); } } catch (FileNotFoundException e) { // Do nothing ... metadata empty } catch (IOException e) { throw new UnifiedRepositoryException("Error reading metadata [" + fileId + "]", e); } finally { IOUtils.closeQuietly(reader); } return metadata; } public void copyFile(Serializable fileId, String destAbsPath, String versionMessage) { throw new UnsupportedOperationException("This operation is not support by this repository"); } public List<RepositoryFile> getDeletedFiles(String origParentFolderPath, String filter) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public List<Character> getReservedChars() { List<Character> charList = new ArrayList<Character>(); String osName = System.getProperty("os.name"); charList.addAll(reservedChars); if (osName.contains("Windows")) { charList.addAll(reservedCharsWindows); } return charList; } @Override public List<Locale> getAvailableLocalesForFileById(Serializable fileId) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public List<Locale> getAvailableLocalesForFileByPath(String relPath) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public List<Locale> getAvailableLocalesForFile(RepositoryFile repositoryFile) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public Properties getLocalePropertiesForFileById(Serializable fileId, String locale) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public Properties getLocalePropertiesForFileByPath(String relPath, String locale) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public Properties getLocalePropertiesForFile(RepositoryFile repositoryFile, String locale) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public void setLocalePropertiesForFileById(Serializable fileId, String locale, Properties properties) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public void setLocalePropertiesForFileByPath(String relPath, String locale, Properties properties) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public void setLocalePropertiesForFile(RepositoryFile repositoryFile, String locale, Properties properties) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public void deleteLocalePropertiesForFile(RepositoryFile repositoryFile, String locale) { throw new UnsupportedOperationException("This operation is not support by this repository"); } @Override public RepositoryFile updateFolder(RepositoryFile file, String versionMessage) { throw new UnsupportedOperationException("This operation is not support by this repository"); } private String getPhysicalFileLocation(String relPath) { if (StringUtils.isEmpty(relPath)) { return relPath; } String physicalFileLocation = relPath; if (relPath.equals("/")) { physicalFileLocation = rootDir.getAbsolutePath(); } else if (relPath.startsWith(rootDir.getAbsolutePath())) { physicalFileLocation = relPath; } else { physicalFileLocation = RepositoryFilenameUtils.concat(rootDir.getAbsolutePath(), relPath.substring(RepositoryFilenameUtils.getPrefixLength(relPath))); } return physicalFileLocation; } }