I try make implementation for comparing the files before they are uploaded.
If file whith name is exist in system ask about create new version or just override it.
Here is the problem, how to get file name?
I can't use receiveUpload(), because after this method file is remove from upload component ?
The problem is that once you start an upload using the Upload component, it can only be interrupted by calling the interruptUpload() method, and you cannot resume anytime later.
The interruption is permanent.
This means you cannot pause in the middle of the upload to see if you already have the file in your system. You have to upload the file all the way.
Considering this drawback, you can sill check in your system if you have the file, after the upload finishes. If you have the file, you can show a confirmation dialog in which you decide wether to keep the file or overwrite.
The following is an example in which I check in the "system" (I just keep a String list with the filenames) if the file has already been uploaded:
public class RestrictingUpload extends Upload implements Upload.SucceededListener, Upload.Receiver {
private List<String> uploadedFilenames;
private ByteArrayOutputStream latestUploadedOutputStream;
public RestrictingUpload() {
setCaption("Upload");
setButtonCaption("Upload file");
addSucceededListener(this);
setReceiver(this);
uploadedFilenames = new ArrayList<String>();
}
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
latestUploadedOutputStream = new ByteArrayOutputStream();
return latestUploadedOutputStream;
}
#Override
public void uploadSucceeded(SucceededEvent event) {
if (fileExistsInSystem(event.getFilename())) {
confirmOverwrite(event.getFilename());
} else {
uploadedFilenames.add(event.getFilename());
}
}
private void confirmOverwrite(final String filename) {
ConfirmDialog confirmDialog = new ConfirmDialog();
String message = String.format("The file %s already exists in the system. Overwrite?", filename);
confirmDialog.show(getUI(), "Overwrite?", message, "Overwrite", "Cancel", new ConfirmDialog.Listener() {
#Override
public void onClose(ConfirmDialog dialog) {
if (dialog.isConfirmed()) {
copyFileToSystem(filename);
}
}
});
}
private void copyFileToSystem(String filename) {
try {
IOUtils.write(latestUploadedOutputStream.toByteArray(), new FileOutputStream(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}
}
private boolean fileExistsInSystem(String filename) {
return uploadedFilenames.contains(filename);
}
}
Note that I have used 2 external libraries:
Apache Commons IO 2.4 (http://mvnrepository.com/artifact/commons-io/commons-io/2.4) for writing to streams
ConfirmDialog from Vaadin Directory (https://vaadin.com/directory#addon/confirmdialog)
You can get the code snippet for this class from Gist: https://gist.github.com/gabrielruiu/9960772 which you can paste into your UI and test it out.
Related
Using nanohttpd I can select a chosen file and start a server to serve that one file.
Is it possible to serve a list of lot of files?
That is, I have lot of files in sd card and I want to serve the selected ones. So how to give an array of file paths of those files and generate and return URL for them, so that I can access them from network.
Not an HTML page which lists all those files and folders.
I have gone through this, this is not what I am referring to. In this it it just lists the root folder and lists them all in a HTML page, for a user to view/select. Not what I am after.
Just an array of server URLs for a selected, chosen list of files in sdcard, which I can then use programmatically.
As of now I have this
protected void onCreate(Bundle savedInstanceState) {
...
server = new Mp3Server();
try {
server.start();
} catch(IOException ioe) {
Log.w("Httpd", "The server could not start.");
}
Log.w("Httpd", "Web server initialized.");
}
...
...
public class Mp3Server extends NanoHTTPD {
public Mp3Server() {
super(8089);
}
#Override
public Response serve(String uri, Method method,
Map<String, String> header, Map<String, String> parameters,
Map<String, String> files) {
String answer = "";
FileInputStream fis = null;
try {
fis = new FileInputStream("/storage/C67A-18F7/Music/music.mp3");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return newChunkedResponse(Status.OK, "audio/mpeg", fis);
}
}
Or do I have to pass the chosen file and start/stop server each time for each file? But this sounds inefficient.
I'm trying to receive a file uploaded to a (citrus) ftp server and verify that the content of the file uploaded is as expected.
I've managed to receive the STOR message (my code below), but I don't know how can I test that content is equals to some text (I'm working with xml, json and csv files).
Can you help me?
Thanks.
#Test
public class SampleFtpTest extends TestNGCitrusTestDesigner {
#Autowired
private FtpServer ftpServer;
#CitrusTest
public void testFileContent() {
Condition waitUntilFileIsUploaded = new Condition() {
#Override
public String getName () {
return "Check files on FTP";
}
#Override
public boolean isSatisfied (TestContext testContext){
return new File("target/ftp/user/anonymous").listFiles().length != 0;
}
#Override
public String getSuccessMessage (TestContext testContext){
return "Files found in FTP!";
}
#Override
public String getErrorMessage (TestContext testContext){
return "No file was found in FTP";
}
};
waitFor().condition(waitUntilFileIsUploaded).seconds(1200L).interval(5000L);
// simulate integration uploading a file...
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(20000L);
Runtime.getRuntime().exec("curl -T /tmp/test.txt ftp://localhost:22222 --user anonymous:secret");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
// don't care about connection related messages
receive(ftpServer);
receive(ftpServer);
receive(ftpServer);
receive(ftpServer);
receive(ftpServer);
// i'd like to assert that the uploaded files content is as expected
receive(ftpServer).header("citrus_ftp_command", FTPCmd.STOR.getCommand());
}
}
I've managed to test the file content adding a ChannelEndpoint which reads the file from the ftp working directory. Then I can test the file content doing this:
receive(fileEndpoint)
.header("file_originalFile", "#contains('/test.txt')#")
.payload(new ClassPathResource("ar/com/jidev/citrus/samples/expected/test.txt"));
For more information I uploaded the full example here
I want to print my file directly from webpage. For that I am using following reference and trying to implement same with ZUL and Composer.
http://tonny-bruckers.blogspot.in/2012/11/printing-files-directly-from-web-page.html
ZUL File :-
<zk>
<applet code = "PrintApplet.class" codebase = "applet/" id="printApplet" width="400px" style="border: 1px" />
<button id="btnClickMe" label="Click Me" sclass="light-btn"/>
</zk>
PrintApplet.class is present inside "WebContent/applet".
public class AppletComposer extends GenericForwardComposer<Window> {
private Applet printApplet;
public void doOverrideAfterComposer(Window comp) throws Exception {
}
public void onClick$btnClickMe(Event event) throws Exception {
String Originalstr = "ByteArrayInputStream Example!";
byte[] Originalbytes = Originalstr.getBytes();
ByteArrayInputStream bis=new ByteArrayInputStream(Originalbytes);
printApplet.invoke("print", bis);
}
}
PrintApplet Class :-
public class PrintApplet extends Applet {
public void init()
{
}
public void print(ByteArrayInputStream bis) throws PrintException
{
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
if (service != null) {
DocFlavor psFormat = DocFlavor.INPUT_STREAM.PDF;
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
DocPrintJob job = service.createPrintJob();
Doc pdfDoc = new SimpleDoc(bis,psFormat, null);
job.print(pdfDoc, attributes);
}
}
}
I am able to invoke PrintApplet with this approach but getting Null as service. PrintApplet is working fine with AppletViewer and with normal Java Application but unable to get default printer service while using the above approach.
First I want to mention that APPLET IS ALWAYS RUN ON CLIENT SIDE and APPLET only communicates to the server which from it is downloaded.
That’s why we have to specify codebase directory, so that we can download the applet on client browser by then JAVA Platform Environment plugin from browser takes on control, which in turn run on client JRE environment.
So we have to be very carefully that JDK environment is installed properly.
To trace applet log we can use of java applet console tool ‘jconsole’.
Steps for APPLET to run properly on client browser :
At browser (firefox,chrome,opera) check whether JAVA Platform plugin is there or not, because to run applet from the browser we require that plugin installed and enabled.
If you are working on linux machine: than it is bit complex,
You can find how to enable plugin for LINUX-BROWSER from here:
http://www.oracle.com/technetwork/java/javase/manual-plugin-install-linux-136395.html
Enable console log for applet, when it executes on client JRE, we can look into it for tracing.
Path : JDK_DIR/bin/jcontrol
[JControl Window][1]
For only development purpose: you can lower the security
We have to clear the cache of applet, every time we build new applet, to reflect the latest change we need to clear the cache first, otherwise it'll load cached applet class.
To clear we can use 'javaws -viewer'
Path : JAVA_HOME/bin/javaws -viewer
[Clear Applet Cache][2]
As per your code, your server side code (zul and composer) are perfect but the problem is at applet code.
You are looking for a default printer in print() method, which are one time configuration codes. It has to be in init().
PrintApplet.java
public class PrintApplet extends Applet {
private static final long serialVersionUID = 1L;
private PrintService service;
public void init()
{
JOptionPane.showMessageDialog(null, "Inside INIT()");
if(null==service){
service = PrintServiceLookup.lookupDefaultPrintService();
System.out.println(service.getName());
} else {
System.out.println(service.getName());
}
}
public void print(String str) throws PrintException
{
JOptionPane.showMessageDialog(null, "Inside print()");
JOptionPane.showMessageDialog(null, "String is:::"+str);
cPrint cP = new cPrint(str, service);
System.out.println((Integer) AccessController.doPrivileged(cP));
}
}
And you need another implementation of AccessController to give access to the default printer locate and print.
cPrint.java
class cPrint implements PrivilegedAction<Object> {
String str;
PrintService service;
public cPrint(String str, PrintService argPrintService) {
this.str = str;
this.service = argPrintService;
};
public Object run() {
// privileged code goes here
InputStream is = null;
try
{
JOptionPane.showMessageDialog(null, "String is:::"+str);
byte[] Originalbytes = str.getBytes();
JOptionPane.showMessageDialog(null, "Original bytes:::"+Originalbytes);
is=new ByteArrayInputStream(Originalbytes);
FileWriter fstream = new FileWriter("/home/test/out.pdf");
BufferedWriter out = new BufferedWriter(fstream);
for (Byte b: Originalbytes) {
out.write(b);
}
out.close();
DocPrintJob printJob = service.createPrintJob();
Doc doc;
DocAttributeSet docAttrSet = new HashDocAttributeSet();
PrintRequestAttributeSet printReqAttr = new HashPrintRequestAttributeSet();
doc = new SimpleDoc(is, DocFlavor.INPUT_STREAM.AUTOSENSE, docAttrSet);
PrintJobWatcher pjDone = new PrintJobWatcher(printJob);
printJob.print(doc, printReqAttr);
pjDone.waitForDone();
// It is now safe to close the input stream
is.close();
}
catch (Exception e) {
e.printStackTrace();
System.out.println(e);
return 1;
}
return 0;
}
static class PrintJobWatcher {
// true iff it is safe to close the print job's input stream
boolean done = false;
PrintJobWatcher(DocPrintJob job) {
// Add a listener to the print job
job.addPrintJobListener(new PrintJobAdapter() {
public void printJobCanceled(PrintJobEvent pje) {
allDone();
}
public void printJobCompleted(PrintJobEvent pje) {
allDone();
}
public void printJobFailed(PrintJobEvent pje) {
allDone();
}
public void printJobNoMoreEvents(PrintJobEvent pje) {
allDone();
}
void allDone() {
synchronized (PrintJobWatcher.this) {
done = true;
PrintJobWatcher.this.notify();
}
}
});
}
public synchronized void waitForDone() {
try {
while (!done) {
wait();
}
} catch (InterruptedException e) {
}
}
}
}
cPrint(str,PrintService)
Where str can be file name if you want file to be print, or byte array string.
Here in my example, I expected byte array, so I create pdf file from byte array given by the applet from the composer and then it'll sent to the default printer to the given PrintService.
So Actual flow for applet in zk to get access for default printer and to print is by this [graph][3].
I have a file with name foo.txt. This file contains some text. I want to achieve following functionality:
I launch program
write something to the file (for example add one row: new string in foo.txt)
I want to get ONLY NEW content of this file.
Can you clarify the best solution of this problem? Also I want resolve related issues: in case if I modify foo.txt I want to see diff.
The closest tool which I found in Java is WatchService but if I understood right this tool can only detect type of event happened on filesystem (create file or delete or modify).
Java Diff Utils is designed for that purpose.
final List<String> originalFileContents = new ArrayList<String>();
final String filePath = "C:/Users/BackSlash/Desktop/asd.txt";
FileListener fileListener = new FileListener() {
#Override
public void fileDeleted(FileChangeEvent paramFileChangeEvent)
throws Exception {
// use this to handle file deletion event
}
#Override
public void fileCreated(FileChangeEvent paramFileChangeEvent)
throws Exception {
// use this to handle file creation event
}
#Override
public void fileChanged(FileChangeEvent paramFileChangeEvent)
throws Exception {
System.out.println("File Changed");
//get new contents
List<String> newFileContents = new ArrayList<String> ();
getFileContents(filePath, newFileContents);
//get the diff between the two files
Patch patch = DiffUtils.diff(originalFileContents, newFileContents);
//get single changes in a list
List<Delta> deltas = patch.getDeltas();
//print the changes
for (Delta delta : deltas) {
System.out.println(delta);
}
}
};
DefaultFileMonitor monitor = new DefaultFileMonitor(fileListener);
try {
FileObject fileObject = VFS.getManager().resolveFile(filePath);
getFileContents(filePath, originalFileContents);
monitor.addFile(fileObject);
monitor.start();
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (FileNotFoundException e) {
//handle
e.printStackTrace();
} catch (IOException e) {
//handle
e.printStackTrace();
}
Where getFileContents is :
void getFileContents(String path, List<String> contents) throws FileNotFoundException, IOException {
contents.clear();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
contents.add(line);
}
}
What I did:
I loaded the original file contents in a List<String>.
I used Apache Commons VFS to listen for file changes, using FileMonitor. You may ask, why? Because WatchService is only available starting from Java 7, while FileMonitor works with at least Java 5 (personal preference, if you prefer WatchService you can use it). note: Apache Commons VFS depends on Apache Commons Logging, you'll have to add both to your build path in order to make it work.
I created a FileListener, then I implemented the fileChanged method.
That method load new contents form the file, and uses Patch.diff to retrieve all differences, then prints them
I created a DefaultFileMonitor, which basically listens for changes to a file, and I added my file to it.
I started the monitor.
After the monitor is started, it will begin listening for file changes.
I want to run an action (with a rule) when a file enters the folder in my alfresco repository. The file needs to be moved to a new folder. The new folder will be named after the metadata property "subject" from the file I uploaded.
I am not able to figure out how to do this. Who got any tips?
(A repository webscript is also an option).
This is how I see it:
import java.util.List;
public class MoveExecuter extends ActionExecuterAbstractBase {
public static final String DESTINATION_FOLDER = "destination-folder";
private FileFolderService fileFolderService;
private NodeService nodeService;
#Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
paramList.add(
new ParameterDefinitionImpl(DESTINATION_FOLDER,
DataTypeDefinition.NODE_REF,
true,
getParamDisplayLabel(METADATA VALUE FROM FIELD SUBJECT FROM INCOMING FILE)));}
public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) {
NodeRef destinationParent = (NodeRef)ruleAction.getParameterValue(DESTINATION_FOLDER);
// if the node exists
if (this.nodeService.exists(destinationParent) == true) {
try {
fileFolderService.move(incomingfile, destinationParent, null);
} catch (FileNotFoundException e) {
// Do nothing
}
if (this.nodeService.exists(destinationParent) == false) {
try {
nodeService.createNode(parentRef, assocTypeQName, assocQName, "metadata field subject");
fileFolderService.move(incomingfile, destinationParent, null);
} catch (FileNotFoundException e) {
// Do nothing
}
}
}
}
For such a simple action I'd just use a JavaScript instead of a java Action.
Install the JavaScript addon from googlecode or github (newer version)
And just write your Javascript code according the api and run it in runtime in the console to test your code.