package pl.net.bluesoft.rnd.pt.ext.cmis.widget;
import com.vaadin.Application;
import com.vaadin.terminal.ClassResource;
import com.vaadin.terminal.StreamResource;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.themes.BaseTheme;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.client.api.Document;
import org.apache.chemistry.opencmis.client.api.Folder;
import org.apache.chemistry.opencmis.client.api.ItemIterable;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolBpmSession;
import pl.net.bluesoft.rnd.processtool.model.BpmTask;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessStateConfiguration;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessStateWidget;
import pl.net.bluesoft.rnd.processtool.ui.widgets.ProcessToolDataWidget;
import pl.net.bluesoft.rnd.processtool.ui.widgets.ProcessToolWidget;
import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AliasName;
import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AutoWiredProperty;
import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.WidgetGroup;
import pl.net.bluesoft.rnd.processtool.ui.widgets.impl.BaseProcessToolVaadinWidget;
import pl.net.bluesoft.rnd.pt.utils.cmis.CmisAtomSessionFacade;
import pl.net.bluesoft.rnd.util.i18n.I18NSource;
import pl.net.bluesoft.util.lang.StringUtil;
import java.io.*;
import java.math.BigInteger;
import java.util.*;
/**
* @author tlipski@bluesoft.net.pl
*/
@AliasName(name = "CmisDocumentList")
@WidgetGroup("cmis-widget")
public class CmisDocumentListWidget extends BaseProcessToolVaadinWidget implements ProcessToolDataWidget {
@AutoWiredProperty
private String repositoryAtomUrl = "http://localhost:8080/nuxeo/atom/cmis";
@AutoWiredProperty
private String repositoryId = "default";
@AutoWiredProperty
private String repositoryUser = "Administrator";
@AutoWiredProperty
private String repositoryPassword = "Administrator";
@AutoWiredProperty
private String rootFolderPath = "/processtool/docs";
@AutoWiredProperty
private String subFolder = "test1";
@AutoWiredProperty
private String newFolderPrefix = "pt_";
@AutoWiredProperty
private String mode = "normal";
@AutoWiredProperty
private String hideMatching = null;
@AutoWiredProperty
private boolean required = false;
private String folderId;
private CmisAtomSessionFacade sessionFacade;
private Folder mainFolder;
private String login;
@Override
public void setContext(ProcessStateConfiguration state, ProcessStateWidget configuration, I18NSource i18NSource,
ProcessToolBpmSession bpmSession, Application application, Set<String> permissions, boolean isOwner) {
super.setContext(state, configuration, i18NSource, bpmSession, application, permissions, isOwner);
login = bpmSession.getUserLogin();
}
@Override
public Collection<String> validateData(BpmTask task, boolean skipRequired) {
if (required && !mainFolder.getChildren().iterator().hasNext()) {
return Arrays.asList("pt.ext.cmis.list.document.validate.upload.document");
} else {
return null;
}
}
@Override
public void saveData(BpmTask task) {
// setSimpleAttribute(folderAttributeName, folderId, processInstance);
}
@Override
public void loadData(BpmTask task) {
sessionFacade = new CmisAtomSessionFacade(repositoryUser, repositoryPassword, repositoryAtomUrl, repositoryId);
mainFolder = sessionFacade.createFolderIfNecessary(newFolderPrefix + task.getProcessInstance().getInternalId(),
rootFolderPath);
if (StringUtil.hasText(subFolder))
mainFolder = sessionFacade.createFolderIfNecessary(subFolder, mainFolder.getPath());
folderId = mainFolder.getId();
}
VerticalLayout vl;
private Component documentListComponent;
@Override
public Component render() {
vl = new VerticalLayout();
Button refreshDocumentList = new Button(getMessage("pt.ext.cmis.list.refresh"));
refreshDocumentList.setIcon(new ClassResource(CmisDocumentListWidget.class, "/img/load-repository.png", getApplication()));
refreshDocumentList.setImmediate(true);
refreshDocumentList.setStyleName(BaseTheme.BUTTON_LINK);
refreshDocumentList.addListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
reload();
}
});
vl.addComponent(refreshDocumentList);
reload();
return vl;
}
private void reload() {
if (documentListComponent != null) {
vl.removeComponent(documentListComponent);
}
if (hasPermission("EDIT", "VIEW")) {
vl.addComponent(documentListComponent = getDocumentList());
}
}
private Component getDocumentList() {
VerticalLayout vl = new VerticalLayout();
vl.setWidth("100%");
ItemIterable<CmisObject> cmisObjectItemIterable = mainFolder.getChildren();
boolean hasAnyDocuments = false;
for (CmisObject co : cmisObjectItemIterable) {
if (co instanceof Document) {
hasAnyDocuments = true;
String name = co.getName();
boolean popup = false;
if (name.contains("__POPUP_ONCE__")) {
popup = true;
name = name.replaceFirst("__POPUP_ONCE__", "");
Map<String, Object> map = new HashMap<String, Object>();
map.put(PropertyIds.NAME, name);
co.updateProperties(map, true);
} else if (name.contains("__POPUP_ALWAYS__")) {
popup = true;
name = name.replaceFirst("__POPUP_ALWAYS__", "");
}
if(hideMatching != null && !"".equals(hideMatching) && name.matches(".*"+hideMatching+".*")){
continue;
}
final Document doc = (Document) co;
HorizontalLayout hl = new HorizontalLayout();
hl.setWidth("100%");
hl.setSpacing(true);
Label label = new Label(name);
label.setWidth("100%");
hl.addComponent(label);
hl.setExpandRatio(label, 1.0f);
final StreamResource resource = new StreamResource(new StreamResource.StreamSource() {
@Override
public InputStream getStream() {
ContentStream cs = doc.getContentStream();
return cs.getStream();
}
}, name, getApplication());
if (popup) {
getApplication().getMainWindow().open(resource, "_blank");
}
Link downloadLink = new Link(getI18NSource().getMessage("pt.ext.cmis.list.document.download"), resource);
downloadLink.setTargetName("_blank");
hl.addComponent(downloadLink);
if (hasPermission("EDIT")) {
Upload upload = new Upload();
upload.setButtonCaption(getI18NSource().getMessage("pt.ext.cmis.list.update.button"));
upload.setReceiver(new UpdateReceiver(doc));
upload.setImmediate(true);
hl.addComponent(upload);
}
vl.addComponent(hl);
}
if ("simple".equalsIgnoreCase(mode)) {
break;
}
}
if (!hasAnyDocuments) {
vl.addComponent(new Label(getI18NSource().getMessage("pt.ext.cmis.list.no-documents")));
}
if (hasPermission("EDIT")) {
if ("normal".equalsIgnoreCase(mode) || !hasAnyDocuments) {
vl.addComponent(new Label(getI18NSource().getMessage("pt.ext.cmis.list.upload")));
Upload upload = new Upload();
upload.setImmediate(true);
upload.setButtonCaption(getI18NSource().getMessage("pt.ext.cmis.list.upload.button"));
upload.setReceiver(new Upload.Receiver() {
@Override
public OutputStream receiveUpload(final String filename, final String MIMEType) {
return new ByteArrayOutputStream() {
@Override
public void close() throws IOException {
super.close();
sessionFacade.uploadDocument(filename, mainFolder, toByteArray(), MIMEType, null);
reload();
}
};
}
});
vl.addComponent(upload);
}
}
return vl;
}
@Override
public void addChild(ProcessToolWidget child) {
throw new IllegalArgumentException("not supported");
}
public String getRepositoryAtomUrl() {
return repositoryAtomUrl;
}
public void setRepositoryAtomUrl(String repositoryAtomUrl) {
this.repositoryAtomUrl = repositoryAtomUrl;
}
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getRepositoryUser() {
return repositoryUser;
}
public void setRepositoryUser(String repositoryUser) {
this.repositoryUser = repositoryUser;
}
public String getRepositoryPassword() {
return repositoryPassword;
}
public void setRepositoryPassword(String repositoryPassword) {
this.repositoryPassword = repositoryPassword;
}
public String getRootFolderPath() {
return rootFolderPath;
}
public void setRootFolderPath(String rootFolderPath) {
this.rootFolderPath = rootFolderPath;
}
public String getNewFolderPrefix() {
return newFolderPrefix;
}
public void setNewFolderPrefix(String newFolderPrefix) {
this.newFolderPrefix = newFolderPrefix;
}
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
public String getSubFolder() {
return subFolder;
}
public void setSubFolder(String subFolder) {
this.subFolder = subFolder;
}
public String getMode() {
return mode;
}
public void setMode(String mode) {
this.mode = mode;
}
public String getFolderId() {
return folderId;
}
public void setFolderId(String folderId) {
this.folderId = folderId;
}
private final class UpdateReceiver implements Upload.Receiver {
private final Document doc;
private UpdateReceiver(Document doc) {
this.doc = doc;
}
@Override
public OutputStream receiveUpload(final String filename, final String MIMEType) {
return new ByteArrayOutputStream() {
@Override
public void close() throws IOException {
super.close();
final byte[] bytes = toByteArray();
Map<String, String> properties = new HashMap();
properties.put(PropertyIds.NAME, filename);
properties.put(PropertyIds.LAST_MODIFIED_BY, login);
ContentStream contentStream = new ContentStream() {
@Override
public long getLength() {
return bytes.length;
}
@Override
public BigInteger getBigLength() {
return BigInteger.valueOf(bytes.length);
}
@Override
public String getMimeType() {
return MIMEType;
}
@Override
public String getFileName() {
return filename;
}
@Override
public InputStream getStream() {
return new ByteArrayInputStream(bytes);
}
@Override
public List<CmisExtensionElement> getExtensions() {
return null;
}
@Override
public void setExtensions(List<CmisExtensionElement> extensions) {
}
};
// doc.checkOut();
doc.setContentStream(contentStream, true);
doc.checkIn(true, properties, contentStream, "");
reload();
}
};
}
}
public void setHideMatching(String hideMatching) {
this.hideMatching = hideMatching;
}
}