blob: 8cecf31b4432365f569211cec9f0f3fc8139caa2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*
*/
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* 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.apache.openaz.xacml.admin.model;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.apache.openaz.xacml.util.XACMLPolicyScanner;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.MethodProperty;
import com.vaadin.server.Resource;
import com.vaadin.ui.TextArea;
import com.vaadin.util.FileTypeResolver;
/**
* A hierarchical container wrapper for a filesystem.
*
* @author Vaadin Ltd.
* @since 3.0
*/
@SuppressWarnings("serial")
public class GitRepositoryContainer extends ItemSetChangeNotifier implements Container.Hierarchical {
private Log logger = LogFactory.getLog(GitRepositoryContainer.class);
/**
* String identifier of a file's "name" property.
*/
public static String PROPERTY_NAME = "Name";
/**
* String identifier of a file's "size" property.
*/
public static String PROPERTY_SIZE = "Size";
/**
* String identifier of a file's "icon" property.
*/
public static String PROPERTY_ICON = "Icon";
/**
* String identifier of a file's "last modified" property.
*/
public static String PROPERTY_LASTMODIFIED = "Last Modified";
/**
* String identifier of a file's "version" property.
*/
public static String PROPERTY_VERSION = "Version";
/**
* String identifier of a file's "status" property.
*/
public static String PROPERTY_STATUS = "Status";
/**
* String identifier of a file's "data" property.
*/
public static String PROPERTY_DATA = "Data";
/**
* List of the string identifiers for the available properties.
*/
public static Collection<String> FILE_PROPERTIES;
private final static Method FILEITEM_LASTMODIFIED;
private final static Method FILEITEM_NAME;
private final static Method FILEITEM_ICON;
private final static Method FILEITEM_SIZE;
private final static Method FILEITEM_VERSION;
private final static Method FILEITEM_STATUS;
private final static Method FILEITEM_DATA;
static {
FILE_PROPERTIES = new ArrayList<String>();
FILE_PROPERTIES.add(PROPERTY_NAME);
FILE_PROPERTIES.add(PROPERTY_ICON);
FILE_PROPERTIES.add(PROPERTY_SIZE);
FILE_PROPERTIES.add(PROPERTY_LASTMODIFIED);
FILE_PROPERTIES.add(PROPERTY_VERSION);
FILE_PROPERTIES.add(PROPERTY_STATUS);
FILE_PROPERTIES.add(PROPERTY_DATA);
FILE_PROPERTIES = Collections.unmodifiableCollection(FILE_PROPERTIES);
try {
FILEITEM_VERSION = FileItem.class.getMethod("getVersion", new Class[]{});
FILEITEM_LASTMODIFIED = FileItem.class.getMethod("lastModified", new Class[] {});
FILEITEM_NAME = FileItem.class.getMethod("getName", new Class[] {});
FILEITEM_ICON = FileItem.class.getMethod("getIcon", new Class[] {});
FILEITEM_SIZE = FileItem.class.getMethod("getSize", new Class[] {});
FILEITEM_STATUS = FileItem.class.getMethod("getStatus", new Class[] {});
FILEITEM_DATA = FileItem.class.getMethod("getData", new Class[] {});
} catch (final NoSuchMethodException e) {
throw new RuntimeException(
"Internal error finding methods in FilesystemContainer");
}
}
private File[] roots = new File[] {};
private FilenameFilter filter = null;
private boolean recursive = true;
private Path repository = null;
/**
* Constructs a new <code>FileSystemContainer</code> with the specified file
* as the root of the filesystem. The files are included recursively.
*
* @param root
* the root file for the new file-system container. Null values
* are ignored.
*/
public GitRepositoryContainer(Path repository, File root) {
super();
this.repository = repository;
if (root != null) {
roots = new File[] { root };
}
this.setContainer(this);
}
/**
* Constructs a new <code>FileSystemContainer</code> with the specified file
* as the root of the filesystem. The files are included recursively.
*
* @param root
* the root file for the new file-system container.
* @param recursive
* should the container recursively contain subdirectories.
*/
public GitRepositoryContainer(Path repository, File root, boolean recursive) {
this(repository, root);
setRecursive(recursive);
this.setContainer(this);
}
/**
* Constructs a new <code>FileSystemContainer</code> with the specified file
* as the root of the filesystem.
*
* @param root
* the root file for the new file-system container.
* @param extension
* the Filename extension (w/o separator) to limit the files in
* container.
* @param recursive
* should the container recursively contain subdirectories.
*/
public GitRepositoryContainer(Path repository, File root, String extension, boolean recursive) {
this(repository, root);
this.setFilter(extension);
setRecursive(recursive);
this.setContainer(this);
}
/**
* Constructs a new <code>FileSystemContainer</code> with the specified root
* and recursivity status.
*
* @param root
* the root file for the new file-system container.
* @param filter
* the Filename filter to limit the files in container.
* @param recursive
* should the container recursively contain subdirectories.
*/
public GitRepositoryContainer(Path repository, File root, FilenameFilter filter, boolean recursive) {
this(repository, root);
this.setFilter(filter);
setRecursive(recursive);
}
/**
* Adds new root file directory. Adds a file to be included as root file
* directory in the <code>FilesystemContainer</code>.
*
* @param root
* the File to be added as root directory. Null values are
* ignored.
*/
public void addRoot(File root) {
if (root != null) {
final File[] newRoots = new File[roots.length + 1];
for (int i = 0; i < roots.length; i++) {
newRoots[i] = roots[i];
}
newRoots[roots.length] = root;
roots = newRoots;
}
}
/**
* Tests if the specified Item in the container may have children. Since a
* <code>FileSystemContainer</code> contains files and directories, this
* method returns <code>true</code> for directory Items only.
*
* @param itemId
* the id of the item.
* @return <code>true</code> if the specified Item is a directory,
* <code>false</code> otherwise.
*/
@Override
public boolean areChildrenAllowed(Object itemId) {
if (logger.isTraceEnabled()) {
logger.trace("areChildrenAllowed: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
return itemId instanceof File && ((File) itemId).canRead()
&& ((File) itemId).isDirectory();
}
/*
* Gets the ID's of all Items who are children of the specified Item. Don't
* add a JavaDoc comment here, we use the default documentation from
* implemented interface.
*/
@Override
public Collection<File> getChildren(Object itemId) {
if (!(itemId instanceof File)) {
return Collections.unmodifiableCollection(new LinkedList<File>());
}
File[] f;
if (filter != null) {
f = ((File) itemId).listFiles(filter);
} else {
f = ((File) itemId).listFiles();
}
if (f == null) {
return Collections.unmodifiableCollection(new LinkedList<File>());
}
final List<File> l = Arrays.asList(f);
Collections.sort(l);
return Collections.unmodifiableCollection(l);
}
/*
* Gets the parent item of the specified Item. Don't add a JavaDoc comment
* here, we use the default documentation from implemented interface.
*/
@Override
public Object getParent(Object itemId) {
if (logger.isTraceEnabled()) {
logger.trace("getParent: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
if (!(itemId instanceof File)) {
return null;
}
return ((File) itemId).getParentFile();
}
/*
* Tests if the specified Item has any children. Don't add a JavaDoc comment
* here, we use the default documentation from implemented interface.
*/
@Override
public boolean hasChildren(Object itemId) {
if (logger.isTraceEnabled()) {
logger.trace("hasChildren: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
if (!(itemId instanceof File)) {
return false;
}
String[] l;
if (filter != null) {
l = ((File) itemId).list(filter);
} else {
l = ((File) itemId).list();
}
return l != null && l.length > 0;
}
/*
* Tests if the specified Item is the root of the filesystem. Don't add a
* JavaDoc comment here, we use the default documentation from implemented
* interface.
*/
@Override
public boolean isRoot(Object itemId) {
if (logger.isTraceEnabled()) {
logger.trace("isRoot: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
if (!(itemId instanceof File)) {
return false;
}
for (int i = 0; i < roots.length; i++) {
if (roots[i].equals(itemId)) {
return true;
}
}
return false;
}
/*
* Gets the ID's of all root Items in the container. Don't add a JavaDoc
* comment here, we use the default documentation from implemented
* interface.
*/
@Override
public Collection<File> rootItemIds() {
File[] f;
// in single root case we use children
if (roots.length == 1) {
if (filter != null) {
f = roots[0].listFiles(filter);
} else {
f = roots[0].listFiles();
}
} else {
f = roots;
}
if (f == null) {
return Collections.unmodifiableCollection(new LinkedList<File>());
}
final List<File> l = Arrays.asList(f);
Collections.sort(l);
return Collections.unmodifiableCollection(l);
}
/**
* Returns <code>false</code> when conversion from files to directories is
* not supported.
*
* @param itemId
* the ID of the item.
* @param areChildrenAllowed
* the boolean value specifying if the Item can have children or
* not.
* @return <code>true</code> if the operaton is successful otherwise
* <code>false</code>.
* @throws UnsupportedOperationException
* if the setChildrenAllowed is not supported.
*/
@Override
public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed)
throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"Conversion file to/from directory is not supported");
}
/**
* Returns <code>false</code> when moving files around in the filesystem is
* not supported.
*
* @param itemId
* the ID of the item.
* @param newParentId
* the ID of the Item that's to be the new parent of the Item
* identified with itemId.
* @return <code>true</code> if the operation is successful otherwise
* <code>false</code>.
* @throws UnsupportedOperationException
* if the setParent is not supported.
*/
@Override
public boolean setParent(Object itemId, Object newParentId)
throws UnsupportedOperationException {
if (logger.isTraceEnabled()) {
logger.trace("setParent: " +
((File)itemId).hashCode() + " " +
((File)itemId).getName() + " to: " +
((File)newParentId).hashCode() + " " +
((File)newParentId).getName());
}
Path path = Paths.get(((File) itemId).getAbsolutePath());
Path parent = Paths.get(((File) newParentId).getAbsolutePath());
boolean ok = path.getParent() == parent;
if (ok) {
fireItemSetChange();
}
return ok;
}
/*
* Tests if the filesystem contains the specified Item. Don't add a JavaDoc
* comment here, we use the default documentation from implemented
* interface.
*/
@Override
public boolean containsId(Object itemId) {
if (logger.isTraceEnabled()) {
logger.trace("containsId: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
if (!(itemId instanceof File)) {
return false;
}
boolean val = false;
// Try to match all roots
for (int i = 0; i < roots.length; i++) {
try {
val |= ((File) itemId).getCanonicalPath().startsWith(
roots[i].getCanonicalPath());
} catch (final IOException e) { //NOPMD
// Exception ignored
}
}
if (val && filter != null) {
val &= filter.accept(((File) itemId).getParentFile(),
((File) itemId).getName());
}
return val;
}
/*
* Gets the specified Item from the filesystem. Don't add a JavaDoc comment
* here, we use the default documentation from implemented interface.
*/
@Override
public Item getItem(Object itemId) {
if (logger.isTraceEnabled()) {
logger.trace("getItem: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
if (!(itemId instanceof File)) {
return null;
}
return new FileItem((File) itemId);
}
public Item updateItem(Object itemId) {
if (logger.isTraceEnabled()) {
logger.trace("updateItem: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
if (!(itemId instanceof File)) {
return null;
}
this.fireItemSetChange();
return new FileItem((File) itemId);
}
/**
* Internal recursive method to add the files under the specified directory
* to the collection.
*
* @param col
* the collection where the found items are added
* @param f
* the root file where to start adding files
*/
private void addItemIds(Collection<File> col, File f) {
File[] l;
if (filter != null) {
l = f.listFiles(filter);
} else {
l = f.listFiles();
}
if (l == null) {
// File.listFiles returns null if File does not exist or if there
// was an IO error (permission denied)
return;
}
final List<File> ll = Arrays.asList(l);
Collections.sort(ll);
for (final Iterator<File> i = ll.iterator(); i.hasNext();) {
final File lf = i.next();
col.add(lf);
if (lf.isDirectory()) {
addItemIds(col, lf);
}
}
}
/*
* Gets the IDs of Items in the filesystem. Don't add a JavaDoc comment
* here, we use the default documentation from implemented interface.
*/
@Override
public Collection<File> getItemIds() {
if (recursive) {
final Collection<File> col = new ArrayList<File>();
for (int i = 0; i < roots.length; i++) {
addItemIds(col, roots[i]);
}
return Collections.unmodifiableCollection(col);
} else {
File[] f;
if (roots.length == 1) {
if (filter != null) {
f = roots[0].listFiles(filter);
} else {
f = roots[0].listFiles();
}
} else {
f = roots;
}
if (f == null) {
return Collections
.unmodifiableCollection(new LinkedList<File>());
}
final List<File> l = Arrays.asList(f);
Collections.sort(l);
return Collections.unmodifiableCollection(l);
}
}
/**
* Gets the specified property of the specified file Item. The available
* file properties are "Name", "Size" and "Last Modified". If propertyId is
* not one of those, <code>null</code> is returned.
*
* @param itemId
* the ID of the file whose property is requested.
* @param propertyId
* the property's ID.
* @return the requested property's value, or <code>null</code>
*/
@Override
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
if (!(itemId instanceof File)) {
return null;
}
if (propertyId.equals(PROPERTY_NAME)) {
return new MethodProperty<Object>(getType(propertyId),
new FileItem((File) itemId), FILEITEM_NAME, null);
}
if (propertyId.equals(PROPERTY_ICON)) {
return new MethodProperty<Object>(getType(propertyId),
new FileItem((File) itemId), FILEITEM_ICON, null);
}
if (propertyId.equals(PROPERTY_SIZE)) {
return new MethodProperty<Object>(getType(propertyId),
new FileItem((File) itemId), FILEITEM_SIZE, null);
}
if (propertyId.equals(PROPERTY_LASTMODIFIED)) {
return new MethodProperty<Object>(getType(propertyId),
new FileItem((File) itemId), FILEITEM_LASTMODIFIED, null);
}
if (propertyId.equals(PROPERTY_VERSION)) {
return new MethodProperty<Object>(getType(propertyId),
new FileItem((File) itemId), FILEITEM_VERSION, null);
}
if (propertyId.equals(PROPERTY_STATUS)) {
return new MethodProperty<Object>(getType(propertyId),
new FileItem((File) itemId), FILEITEM_STATUS, null);
}
if (propertyId.equals(PROPERTY_DATA)) {
return new MethodProperty<Object>(getType(propertyId),
new FileItem((File) itemId), FILEITEM_DATA, null);
}
return null;
}
/**
* Gets the collection of available file properties.
*
* @return Unmodifiable collection containing all available file properties.
*/
@Override
public Collection<String> getContainerPropertyIds() {
return FILE_PROPERTIES;
}
/**
* Gets the specified property's data type. "Name" is a <code>String</code>,
* "Size" is a <code>Long</code>, "Last Modified" is a <code>Date</code>. If
* propertyId is not one of those, <code>null</code> is returned.
*
* @param propertyId
* the ID of the property whose type is requested.
* @return data type of the requested property, or <code>null</code>
*/
@Override
public Class<?> getType(Object propertyId) {
if (propertyId.equals(PROPERTY_NAME)) {
return String.class;
}
if (propertyId.equals(PROPERTY_ICON)) {
return Resource.class;
}
if (propertyId.equals(PROPERTY_SIZE)) {
return Long.class;
}
if (propertyId.equals(PROPERTY_LASTMODIFIED)) {
return Date.class;
}
if (propertyId.equals(PROPERTY_VERSION)) {
return String.class;
}
if (propertyId.equals(PROPERTY_STATUS)) {
return TextArea.class;
}
if (propertyId.equals(PROPERTY_DATA)) {
return Object.class;
}
return null;
}
/**
* Internal method to recursively calculate the number of files under a root
* directory.
*
* @param f
* the root to start counting from.
*/
private int getFileCounts(File f) {
File[] l;
if (filter != null) {
l = f.listFiles(filter);
} else {
l = f.listFiles();
}
if (l == null) {
return 0;
}
int ret = l.length;
for (int i = 0; i < l.length; i++) {
if (l[i].isDirectory()) {
ret += getFileCounts(l[i]);
}
}
return ret;
}
/**
* Gets the number of Items in the container. In effect, this is the
* combined amount of files and directories.
*
* @return Number of Items in the container.
*/
@Override
public int size() {
if (recursive) {
int counts = 0;
for (int i = 0; i < roots.length; i++) {
counts += getFileCounts(roots[i]);
}
return counts;
} else {
File[] f;
if (roots.length == 1) {
if (filter != null) {
f = roots[0].listFiles(filter);
} else {
f = roots[0].listFiles();
}
} else {
f = roots;
}
if (f == null) {
return 0;
}
return f.length;
}
}
/**
* A Item wrapper for files in a filesystem.
*
* @author Vaadin Ltd.
* @since 3.0
*/
public class FileItem implements Item {
/**
* The wrapped file.
*/
private final File file;
private Object data = null;
/**
* Constructs a FileItem from a existing file.
*/
private FileItem(File file) {
if (logger.isTraceEnabled()) {
logger.trace("FileItem constructor: " + file.hashCode() + " " + file.getName());
}
this.file = file;
}
/*
* Gets the specified property of this file. Don't add a JavaDoc comment
* here, we use the default documentation from implemented interface.
*/
@Override
public Property<?> getItemProperty(Object id) {
return getContainerProperty(file, id);
}
/*
* Gets the IDs of all properties available for this item Don't add a
* JavaDoc comment here, we use the default documentation from
* implemented interface.
*/
@Override
public Collection<String> getItemPropertyIds() {
return getContainerPropertyIds();
}
/**
* Calculates a integer hash-code for the Property that's unique inside
* the Item containing the Property. Two different Properties inside the
* same Item contained in the same list always have different
* hash-codes, though Properties in different Items may have identical
* hash-codes.
*
* @return A locally unique hash-code as integer
*/
@Override
public int hashCode() {
return file.hashCode() ^ GitRepositoryContainer.this.hashCode();
}
/**
* Tests if the given object is the same as the this object. Two
* Properties got from an Item with the same ID are equal.
*
* @param obj
* an object to compare with this object.
* @return <code>true</code> if the given object is the same as this
* object, <code>false</code> if not
*/
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof FileItem)) {
return false;
}
final FileItem fi = (FileItem) obj;
return fi.getHost() == getHost() && fi.file.equals(file);
}
/**
* Gets the host of this file.
*/
private GitRepositoryContainer getHost() {
return GitRepositoryContainer.this;
}
/**
* Gets the file's version
*
* @return Integer
*/
public String getVersion() {
/*
* If its a directory, there is no version
*/
if (this.file.isDirectory()) {
return null;
}
try {
return XACMLPolicyScanner.getVersion(Paths.get(this.file.getAbsolutePath()));
} catch (IOException e) {
logger.error("Could not get version: " + e);
return "n/a";
}
}
/**
* Gets the last modified date of this file.
*
* @return Date
*/
public Date lastModified() {
return new Date(file.lastModified());
}
/**
* Gets the name of this file.
*
* @return file name of this file.
*/
public String getName() {
return file.getName();
}
public File getFile() {
return file;
}
/**
* Gets the icon of this file.
*
* @return the icon of this file.
*/
public Resource getIcon() {
return FileTypeResolver.getIcon(file);
}
/**
* Gets the size of this file.
*
* @return size
*/
public Long getSize() {
if (file.isDirectory()) {
return null;
}
return file.length();
}
/**
* Gets the status of this file.
*
* @return status of this file.
*/
public TextArea getStatus() {
TextArea area = null;
try {
Path repoPath = this.getHost().repository;
Git git = Git.open(repoPath.toFile());
//
// I would like to use absolutePath, but that seems to barf when
// we try to relativize this if a full path is not given.
//
Path relativePath = repoPath.relativize(Paths.get(this.file.getPath()));
Status status = git.status().addPath(relativePath.toString()).call();
if (logger.isDebugEnabled()) {
logger.debug(this.file.getAbsolutePath());
logger.debug("Added: " + status.getAdded());
logger.debug("Changed: " + status.getChanged());
logger.debug("Conflicting: " + status.getConflicting());
logger.debug("Missing: " + status.getMissing());
logger.debug("Modified: " + status.getModified());
logger.debug("Removed: " + status.getRemoved());
logger.debug("Uncommitted: " + status.getUncommittedChanges());
logger.debug("Untracked: " + status.getUntracked());
logger.debug("Untracked folders; " + status.getUntrackedFolders());
}
//
// Are we a file or directory?
//
StringBuffer buffer = new StringBuffer();
int length = 0;
if (this.file.isFile()) {
if (status.getAdded().contains(relativePath.toString())) {
buffer.append("Added" + "\n");
length++;
}
if (status.getChanged().contains(relativePath.toString())) {
buffer.append("Changed" + "\n");
length++;
}
if (status.getConflicting().contains(relativePath.toString())) {
buffer.append("Conflicting" + "\n");
length++;
}
if (status.getMissing().contains(relativePath.toString())) {
buffer.append("Missing" + "\n");
length++;
}
if (status.getModified().contains(relativePath.toString())) {
buffer.append("Modified" + "\n");
length++;
}
if (status.getRemoved().contains(relativePath.toString())) {
buffer.append("Removed" + "\n");
length++;
}
if (status.getUncommittedChanges().contains(relativePath.toString())) {
buffer.append("Uncommitted" + "\n");
length++;
}
if (status.getUntracked().contains(relativePath.toString())) {
buffer.append("Untracked (New)" + "\n");
length++;
}
if (status.getUntrackedFolders().contains(relativePath.toString())) {
buffer.append("Untracked Folders (New)" + "\n");
length++;
}
} else if (this.file.isDirectory()) {
if (status.getUntracked().size() > 0) {
buffer.append("Untracked (New)" + "\n");
length++;
}
if (status.getUntrackedFolders().size() > 0) {
buffer.append("Untracked Folders (New)" + "\n");
length++;
}
}
if (length > 0) {
area = new TextArea();
area.setValue(buffer.toString().trim());
area.setWidth("100.0%");
area.setRows(length);
area.setReadOnly(true);
}
} catch (IOException | NoWorkTreeException | GitAPIException e) {
logger.error(e);
}
return area;
}
/**
* Gets the file's data
*
* @return file data
*/
public Object getData() {
return this.data;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
// if ("".equals(file.getName())) {
// return file.getAbsolutePath();
// }
return file.getName();
}
/**
* Filesystem container does not support adding new properties.
*
* @see com.vaadin.data.Item#addItemProperty(Object, Property)
*/
@Override
public boolean addItemProperty(Object id, @SuppressWarnings("rawtypes") Property property) throws UnsupportedOperationException {
throw new UnsupportedOperationException("Filesystem container does not support adding new properties");
}
/**
* Filesystem container does not support removing properties.
*
* @see com.vaadin.data.Item#removeItemProperty(Object)
*/
@Override
public boolean removeItemProperty(Object id) throws UnsupportedOperationException {
throw new UnsupportedOperationException("Filesystem container does not support property removal");
}
}
/**
* Generic file extension filter for displaying only files having certain
* extension.
*
* @author Vaadin Ltd.
* @since 3.0
*/
public class FileExtensionFilter implements FilenameFilter, Serializable {
private final String filter;
/**
* Constructs a new FileExtensionFilter using given extension.
*
* @param fileExtension
* the File extension without the separator (dot).
*/
public FileExtensionFilter(String fileExtension) {
filter = "." + fileExtension;
}
/**
* Allows only files with the extension and directories.
*
* @see java.io.FilenameFilter#accept(File, String)
*/
@Override
public boolean accept(File dir, String name) {
if (name.endsWith(filter)) {
return true;
}
return new File(dir, name).isDirectory();
}
}
/**
* Returns the file filter used to limit the files in this container.
*
* @return Used filter instance or null if no filter is assigned.
*/
public FilenameFilter getFilter() {
return filter;
}
/**
* Sets the file filter used to limit the files in this container.
*
* @param filter
* The filter to set. <code>null</code> disables filtering.
*/
public void setFilter(FilenameFilter filter) {
this.filter = filter;
}
/**
* Sets the file filter used to limit the files in this container.
*
* @param extension
* the Filename extension (w/o separator) to limit the files in
* container.
*/
public void setFilter(String extension) {
filter = new FileExtensionFilter(extension);
}
/**
* Is this container recursive filesystem.
*
* @return <code>true</code> if container is recursive, <code>false</code>
* otherwise.
*/
public boolean isRecursive() {
return recursive;
}
/**
* Sets the container recursive property. Set this to false to limit the
* files directly under the root file.
* <p>
* Note : This is meaningful only if the root really is a directory.
* </p>
*
* @param recursive
* the New value for recursive property.
*/
public void setRecursive(boolean recursive) {
this.recursive = recursive;
}
/*
* (non-Javadoc)
*
* @see com.vaadin.data.Container#addContainerProperty(java.lang.Object,
* java.lang.Class, java.lang.Object)
*/
@Override
public boolean addContainerProperty(Object propertyId, Class<?> type,
Object defaultValue) throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"File system container does not support this operation");
}
/*
* (non-Javadoc)
*
* @see com.vaadin.data.Container#addItem()
*/
@Override
public Object addItem() throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"Git repository container does not support this operation");
}
/*
* (non-Javadoc)
*
* @see com.vaadin.data.Container#addItem(java.lang.Object)
*/
@Override
public Item addItem(Object itemId) throws UnsupportedOperationException {
if (! (itemId instanceof File)) {
throw new UnsupportedOperationException(
"Git repository container does not support this operation for Objects that are not files.");
}
if (logger.isTraceEnabled()) {
logger.trace("addItem: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
fireItemSetChange();
return new FileItem((File) itemId);
}
/*
* (non-Javadoc)
*
* @see com.vaadin.data.Container#removeAllItems()
*/
@Override
public boolean removeAllItems() throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"File system container does not support this operation");
}
/*
* (non-Javadoc)
*
* @see com.vaadin.data.Container#removeItem(java.lang.Object)
*/
@Override
public boolean removeItem(Object itemId)
throws UnsupportedOperationException {
if (logger.isTraceEnabled()) {
logger.trace("removeItem: " + ((File)itemId).hashCode() + " " + ((File)itemId).getName());
}
fireItemSetChange();
return true;
}
/*
* (non-Javadoc)
*
* @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object )
*/
@Override
public boolean removeContainerProperty(Object propertyId)
throws UnsupportedOperationException {
throw new UnsupportedOperationException(
"File system container does not support this operation");
}
public Object getRoot(int index) {
if (index >= this.roots.length) {
return null;
}
return this.roots[index];
}
}