package open.dolphin.impl.img;
import java.awt.Window;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.nio.channels.FileChannel;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
import open.dolphin.client.ClientContext;
import open.dolphin.client.ImageEntry;
import open.dolphin.exception.DolphinException;
import open.dolphin.helper.FileListTransferable;
/**
* SchemaHolderTransferHandler
*
* @author Kazushi Minagawa. Digital Globe, Inc.
*
*/
public class ImageTableTransferHandler extends TransferHandler {
// From StackOverFlow
private static DataFlavor nixFileDataFlavor;
static {
try {
nixFileDataFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
} catch (Exception e) {
}
}
private final AbstractBrowser context;
private JTable sourceTable;
public ImageTableTransferHandler(AbstractBrowser context) {
this.context = context;
}
@Override
protected Transferable createTransferable(JComponent c) {
sourceTable = (JTable) c;
int row = sourceTable.getSelectedRow();
int col = sourceTable.getSelectedColumn();
if (row != -1 && col != -1) {
ImageEntry entry = (ImageEntry) sourceTable.getValueAt(row, col);
if (entry != null) {
File f = new File(entry.getPath());
File[] files = new File[1];
files[0] = f;
Transferable tr = new FileListTransferable(files);
return tr;
} else {
return null;
}
}
return null;
}
@Override
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
@Override
protected void exportDone(JComponent c, Transferable data, int action) {
sourceTable = null;
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
if (!canImport(support)) {
return false;
}
//s.oh^ 2014/05/07 PDF・画像タブの改善
Window parent = SwingUtilities.getWindowAncestor(context.getUI());
String msg1 = ClientContext.getMyBundle(ImageTableTransferHandler.class).getString("waring.cannotMove");
String msg2 = ClientContext.getMyBundle(ImageTableTransferHandler.class).getString("warning.cannotCopy");
if(context.isScanning(parent, (context.dropIsMove()) ? msg1 : msg2)) {
return false;
}
//s.oh$
try {
// Drag & Drop されたファイルのリストを得る
Transferable t = support.getTransferable();
java.util.List<File> files = null;
if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
files = (java.util.List<File>)t.getTransferData(DataFlavor.javaFileListFlavor);
}
//jdk1.6 nix
else if (support.isDataFlavorSupported(nixFileDataFlavor)){
files = getDropedFiles((String)t.getTransferData(nixFileDataFlavor));
}
List<File> allFiles = new ArrayList<>();
for (File file : files) {
if (!file.isDirectory()) {
String name = file.getName();
if (name.startsWith(".")) {
continue;
}
if (file.length()==0L) {
continue;
}
allFiles.add(file);
} else {
//s.oh^ 2014/05/30 PDF・画像タブの改善
//listAll(file, allFiles);
parseDirectory(file);
//s.oh$
}
}
if (allFiles.size() > 0) {
parseFiles(allFiles);
}
sourceTable = null;
return true;
} catch (UnsupportedFlavorException | IOException ufe) {
ufe.printStackTrace(System.err);
}
sourceTable = null;
return false;
}
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
boolean canImport = true;
canImport = canImport && support.isDrop();
canImport = canImport && ((JTable)support.getComponent()!=sourceTable);
boolean isFile = (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor) || support.isDataFlavorSupported(nixFileDataFlavor));
canImport = canImport && isFile;
return canImport;
}
private void parseFiles(final List<File> imageFiles) {
final javax.swing.SwingWorker worker = new javax.swing.SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
String baseDir = context.getImageBase();
if (baseDir == null) {
return null;
}
String patientId = context.getContext().getPatient().getPatientId();
StringBuilder sb = new StringBuilder();
sb.append(baseDir).append(File.separator).append(patientId);
String dirStr = sb.toString();
//s.oh^ 他プロセス連携
if(context instanceof DefaultBrowserEx || context instanceof DefaultBrowser || context instanceof FCRBrowser) {
dirStr = context.getNowLocation();
}
//s.oh$
File dir = new File(dirStr);
if (!dir.exists()) {
boolean ok = dir.mkdirs();
if (!ok) {
String errMsg = ClientContext.getMyBundle(ImageTableTransferHandler.class).getString("error.cannotCreateDirectory");
throw new DolphinException(errMsg);
}
dir.setExecutable(true, false);
dir.setWritable(true, false);
}
for (File src : imageFiles) {
File dest = new File(dirStr, src.getName());
//s.oh^ 機能改善
boolean save = true;
if(dest.exists()) {
Window parent = SwingUtilities.getWindowAncestor(context.getUI());
String question = ClientContext.getMyBundle(ImageTableTransferHandler.class).getString("question.overrideFile");
int ret = JOptionPane.showConfirmDialog(parent, question, ClientContext.getString("productString"), JOptionPane.OK_CANCEL_OPTION);
if(ret != JOptionPane.OK_OPTION) {
save = false;
}
}
if(save) {
FileChannel in = (new FileInputStream(src)).getChannel();
FileChannel out = (new FileOutputStream(dest)).getChannel();
in.transferTo(0, src.length(), out);
in.close();
out.close();
dest.setLastModified(src.lastModified());
}
//s.oh$
}
if (context.dropIsMove()) {
while(imageFiles.size()>0) {
File delete = imageFiles.remove(0);
delete.delete();
}
}
return null;
}
@Override
protected void done() {
try {
get();
//s.oh^ 他プロセス連携
//context.scan(context.getImgLocation());
if(context instanceof DefaultBrowserEx || context instanceof DefaultBrowser || context instanceof FCRBrowser) {
context.scan(context.getNowLocation());
}else{
context.scan(context.getImgLocation());
}
//s.oh$
} catch (InterruptedException ex) {
java.util.logging.Logger.getLogger(this.getClass().getName()).warning(ex.getMessage());
} catch (ExecutionException ex) {
java.util.logging.Logger.getLogger(this.getClass().getName()).warning(ex.getMessage());
Window parent = SwingUtilities.getWindowAncestor(context.getUI());
//String message = "ファイルをコピーできません。\n" + ex.getMessage();
String fmt = ClientContext.getMyBundle(ImageTableTransferHandler.class).getString("messageFormat.cannotCopy");
MessageFormat msf = new MessageFormat(fmt);
String message =msf.format(new Object[]{ex.getMessage()});
String title = ClientContext.getFrameTitle(context.getTitle());
JOptionPane.showMessageDialog(parent, message, title, JOptionPane.WARNING_MESSAGE);
}
}
};
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue().equals(SwingWorker.StateValue.STARTED)) {
//context.getProgressBar().setIndeterminate(true);
} else if (evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
//context.getProgressBar().setIndeterminate(false);
//context.getProgressBar().setValue(0);
worker.removePropertyChangeListener(this);
}
}
});
worker.execute();
}
//s.oh^ 2014/05/30 PDF・画像タブの改善
private void parseDirectory(final File srcDir) {
final javax.swing.SwingWorker worker = new javax.swing.SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
String baseDir = context.getImageBase();
if (baseDir == null) {
return null;
}
String patientId = context.getContext().getPatient().getPatientId();
StringBuilder sb = new StringBuilder();
sb.append(baseDir).append(File.separator).append(patientId);
String dirStr = sb.toString();
if(context instanceof DefaultBrowserEx || context instanceof DefaultBrowser || context instanceof FCRBrowser) {
dirStr = context.getNowLocation();
}
File destDir = new File(dirStr, srcDir.getName());
if(destDir.exists()) {
Window parent = SwingUtilities.getWindowAncestor(context.getUI());
String question = ClientContext.getMyBundle(ImageTableTransferHandler.class).getString("question.overrideFolder");
int ret = JOptionPane.showConfirmDialog(parent, question, ClientContext.getString("productString"), JOptionPane.OK_CANCEL_OPTION);
if(ret != JOptionPane.OK_OPTION) {
return null;
}
}
copyDir(destDir, srcDir);
if (context.dropIsMove()) {
removeDir(srcDir);
}
return null;
}
@Override
protected void done() {
try {
get();
if(context instanceof DefaultBrowserEx || context instanceof DefaultBrowser || context instanceof FCRBrowser) {
context.scan(context.getNowLocation());
}else{
context.scan(context.getImgLocation());
}
} catch (InterruptedException ex) {
java.util.logging.Logger.getLogger(this.getClass().getName()).warning(ex.getMessage());
} catch (ExecutionException ex) {
java.util.logging.Logger.getLogger(this.getClass().getName()).warning(ex.getMessage());
Window parent = SwingUtilities.getWindowAncestor(context.getUI());
//String message = "ファイルをコピーできません。\n" + ex.getMessage();
String fmt = ClientContext.getMyBundle(ImageTableTransferHandler.class).getString("messageFormat.cannotCopy");
MessageFormat msf = new MessageFormat(fmt);
String message =msf.format(new Object[]{ex.getMessage()});
String title = ClientContext.getFrameTitle(context.getTitle());
JOptionPane.showMessageDialog(parent, message, title, JOptionPane.WARNING_MESSAGE);
}
}
};
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue().equals(SwingWorker.StateValue.STARTED)) {
} else if (evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
worker.removePropertyChangeListener(this);
}
}
});
worker.execute();
}
private void copyDir(File destDir, File srcDir) throws FileNotFoundException, IOException {
if(!destDir.exists() && !destDir.mkdirs()) {
return;
}
File[] files = srcDir.listFiles();
for(File file : files) {
if(file.isDirectory()) {
File dir = new File(destDir, file.getName());
copyDir(dir, file);
}else{
File destFile = new File(destDir, file.getName());
FileChannel in = (new FileInputStream(file)).getChannel();
FileChannel out = (new FileOutputStream(destFile)).getChannel();
in.transferTo(0, file.length(), out);
in.close();
out.close();
destFile.setLastModified(file.lastModified());
}
}
}
private void removeDir(File dir) {
if(!dir.exists()) {
return;
}
if(dir.isFile()) {
dir.delete();
}else if(dir.isDirectory()) {
File[] files = dir.listFiles();
for(int i = 0; i < files.length; i++) {
removeDir(files[i]);
}
dir.delete();
}
}
//s.oh$
private void listAll(File dir, List<File> list) {
File[] files = dir.listFiles();
for (File f : files) {
if (f.isDirectory()) {
listAll(f, list);
} else {
list.add(f);
}
}
}
private List<File> getDropedFiles(String data) {
List<File> files = new ArrayList<>(2);
for(StringTokenizer st = new StringTokenizer(data, "\r\n"); st.hasMoreTokens();) {
String token = st.nextToken().trim();
if(token.startsWith("#") || token.isEmpty()) {
// comment line, by RFC 2483
continue;
}
try {
files.add(new File(new URI(token)));
} catch(Exception e) {
e.printStackTrace(System.err);
}
}
return files;
}
}