/** * Content provider that takes an enum class as input an provides its elements. * * @author Simon Templer */ public class EnumContentProvider implements IStructuredContentProvider { private static final ALogger log = ALoggerFactory.getLogger(EnumContentProvider.class); private static EnumContentProvider instance; /** * Get the content provider singleton instance. * * @return the content provider instance */ public static EnumContentProvider getInstance() { synchronized (EnumContentProvider.class) { if (instance == null) { instance = new EnumContentProvider(); } } return instance; } /** Default constructor. */ protected EnumContentProvider() { super(); } /** @see IContentProvider#dispose() */ @Override public void dispose() { // do nothing } /** @see IContentProvider#inputChanged(Viewer, Object, Object) */ @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // do nothing } /** @see IStructuredContentProvider#getElements(Object) */ @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof Class<?> && ((Class<?>) inputElement).isEnum()) { @SuppressWarnings("unchecked") Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) inputElement; try { Method method = enumClass.getMethod("values"); return (Object[]) method.invoke(null); } catch (Exception e) { log.error("Could not get values from enum."); } } return new Object[] {}; } }
/** * Extension for {@link ResourceAdvisor}s * * @author Simon Templer */ public class ResourceAdvisorExtension extends AbstractExtension<ResourceAdvisor, ResourceAdvisorDescriptor> { /** {@link ResourceAdvisor} factory based on a {@link IConfigurationElement} */ private static class ConfigurationFactory extends AbstractConfigurationFactory<ResourceAdvisor> implements ResourceAdvisorDescriptor { /** * Create the {@link ResourceAdvisor} factory * * @param conf the configuration element */ protected ConfigurationFactory(IConfigurationElement conf) { super(conf, "class"); } /** @see ExtensionObjectFactory#dispose(Object) */ @Override public void dispose(ResourceAdvisor advisor) { // do nothing } /** @see ExtensionObjectDefinition#getDisplayName() */ @Override public String getDisplayName() { return getIdentifier(); } /** @see ExtensionObjectDefinition#getIdentifier() */ @Override public String getIdentifier() { return conf.getAttribute("id"); } @Override public Set<IContentType> getAssociatedTypes() { IConfigurationElement[] children = conf.getChildren("contentType"); if (children != null) { Set<IContentType> result = new HashSet<IContentType>(); for (IConfigurationElement child : children) { String id = child.getAttribute("ref"); IContentType ct = Platform.getContentTypeManager().getContentType(id); if (ct != null) { result.add(ct); } else { log.error( MessageFormat.format("Content type with ID {0} not known by the platform", id)); } } return result; } else { return Collections.emptySet(); } } } /** The extension point ID */ public static final String ID = "eu.esdihumboldt.hale.io.resource"; private static final ALogger log = ALoggerFactory.getLogger(ResourceAdvisorExtension.class); /** Default resource advisor */ private static final ResourceAdvisor DEFAULT = new DefaultResourceAdvisor(); private static ResourceAdvisorExtension instance; /** * Get the I/O provider extension instance * * @return the extension instance */ public static ResourceAdvisorExtension getInstance() { if (instance == null) { instance = new ResourceAdvisorExtension(); } return instance; } /** Default constructor */ private ResourceAdvisorExtension() { super(ID); } @Override protected ResourceAdvisorDescriptor createFactory(IConfigurationElement conf) throws Exception { if (conf.getName().equals("advisor")) { return new ConfigurationFactory(conf); } return null; } /** * Create an I/O advisor for the given content type. * * @param contentType the content type, may be <code>null</code> * @return the resource advisor for that content type or a default resource advisor */ public ResourceAdvisor getAdvisor(IContentType contentType) { if (contentType == null) { return DEFAULT; } boolean error = false; for (ResourceAdvisorDescriptor factory : getFactories()) { if (factory.getAssociatedTypes().contains(contentType)) { try { return factory.createExtensionObject(); } catch (Exception e) { log.error("Could not create resource advisor " + factory.getIdentifier(), e); error = true; } } } if (error) { log.warn( "Using default resource advisor as fall-back for content type " + contentType.getName()); } return DEFAULT; } }
/** * Upload form for new projects. * * @author Simon Templer */ public class UploadForm extends Form<Void> { private static final long serialVersionUID = -8077630706189091706L; private static final ALogger log = ALoggerFactory.getLogger(UploadForm.class); private final FileUploadField file; private final TextField<String> identifier; private Set<String> allowedContentTypes = null; private String customTypeErrorMessage = null; @SpringBean private ProjectScavenger projects; /** @see Form#Form(String) */ public UploadForm(String id) { super(id); // multipart always needed for uploads setMultiPart(true); // input field for identifier text identifier = new TextField<String>("identifier", new Model<String>()); // pattern validator identifier.add(new PatternValidator("[A-Za-z0-9 _\\-]+")); // validator that checks if the project name is already taken identifier.add( new IValidator<String>() { private static final long serialVersionUID = 275885544279441469L; @Override public void validate(IValidatable<String> validatable) { String name = validatable.getValue(); for (String project : projects.getResources()) { // ignore case to avoid confusion if (name.equalsIgnoreCase(project)) { validatable.error(new ValidationError().setMessage("Identifier already in use")); break; } } } }); FieldMessage identifierMessage = new FieldMessage( "identifierMessage", new Model<String>("Unique identifier for the project"), identifier); identifier.add(new FieldValidatingBehavior("onblur", identifierMessage)); identifier.setOutputMarkupId(true); identifier.setRequired(true); // identifier.add(new DefaultFocus()); XXX not working well with ajax add(identifier); add(identifierMessage); // Add one file input field add(file = new FileUploadField("file")); add(new FeedbackPanel("feedback")); addAllowedContentType("application/zip"); addAllowedContentType("application/x-zip"); addAllowedContentType("application/x-zip-compressed"); addAllowedContentType("application/octet-stream"); // setCustomTypeErrorMessage("Only ZIP archives are supported for upload"); setMaxSize(Bytes.megabytes(20)); } /** * Add an allowed content type. If none is added, any content type is allowed. * * @param contentType the content type to add */ public void addAllowedContentType(String contentType) { if (allowedContentTypes == null) { allowedContentTypes = new HashSet<String>(); } allowedContentTypes.add(contentType); } /** * Check if the given content type is allowed for upload * * @param contentType the content type * @return if the upload shall be allowed */ protected boolean checkContentType(String contentType) { if (allowedContentTypes == null) { return true; } else { return allowedContentTypes.contains(contentType); } } /** @see Form#onSubmit() */ @Override protected void onSubmit() { final String project = identifier.getModel().getObject(); try { final FileUpload upload = file.getFileUpload(); if (upload != null) { File dir = projects.reserveResourceId(project); // File target = new File(dir, upload.getClientFileName()); String type = upload.getContentType(); if (checkContentType(type)) { // IOUtils.copy(upload.getInputStream(), new FileOutputStream(target)); // try extracting the archive IOUtils.extract(dir, new BufferedInputStream(upload.getInputStream())); // trigger scan after upload projects.triggerScan(); info("Successfully uploaded project"); onUploadSuccess(); } else { projects.releaseResourceId(project); error(getTypeErrorMessage(type)); } } else { warn("Please provide a file for upload"); } } catch (ScavengerException e) { error(e.getMessage()); } catch (Exception e) { projects.releaseResourceId(project); log.error("Error while uploading file", e); error("Error saving the file"); } } /** Called after a successful upload. */ protected void onUploadSuccess() { setResponsePage(ProjectsPage.class); } /** * Get the error message if the upload of the given type is not supported * * @param type the content type * @return the error message */ protected String getTypeErrorMessage(String type) { if (customTypeErrorMessage != null) { return customTypeErrorMessage; } else { return "Files of type " + type + " are not supported."; } } /** @see Form#onFileUploadException(FileUploadException, Map) */ @Override protected void onFileUploadException(FileUploadException e, Map<String, Object> model) { if (e instanceof SizeLimitExceededException) { final String msg = "Only files up to " + bytesToString(getMaxSize(), Locale.US) + " can be uploaded."; error(msg); } else { final String msg = "Error uploading the file: " + e.getLocalizedMessage(); error(msg); log.warn(msg, e); } } /** @param customTypeErrorMessage the customTypeErrorMessage to set */ public void setCustomTypeErrorMessage(String customTypeErrorMessage) { this.customTypeErrorMessage = customTypeErrorMessage; } /** * Convert {@link Bytes} to a string, produces a prettier output than {@link * Bytes#toString(Locale)} * * @param bytes the bytes * @param locale the locale * @return the converted string */ public static String bytesToString(Bytes bytes, Locale locale) { if (bytes.bytes() >= 0) { if (bytes.terabytes() >= 1.0) { return unitString(bytes.terabytes(), "TB", locale); } if (bytes.gigabytes() >= 1.0) { return unitString(bytes.gigabytes(), "GB", locale); } if (bytes.megabytes() >= 1.0) { return unitString(bytes.megabytes(), "MB", locale); } if (bytes.kilobytes() >= 1.0) { return unitString(bytes.kilobytes(), "KB", locale); } return Long.toString(bytes.bytes()) + " bytes"; } else { return "N/A"; } } private static String unitString(final double value, final String units, final Locale locale) { return StringValue.valueOf(value, locale) + " " + units; } }