Files
secondo/Javagui/viewer/PDFRelCreator.java

547 lines
14 KiB
Java
Raw Normal View History

2026-01-23 17:03:45 +08:00
package viewer;
import gui.SecondoObject;
import gui.ViewerControl;
import tools.Base64Encoder;
import tools.Reporter;
import sj.lang.*;
import java.io.*;
import java.util.Stack;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.text.SimpleDateFormat;
import java.util.Date;
enum FORMAT{PDF,JPG}
interface ProgressListener{
public void progress(int count, String name);
public void finished();
};
public class PDFRelCreator extends SecondoViewer implements ProgressListener{
private static IntByReference errorCode= new IntByReference();
private static IntByReference errorPos = new IntByReference();
private static ListExpr resultList= new ListExpr();
private static StringBuffer errorMessage = new StringBuffer();
private static boolean haltOnError = true;
private static BufferedReader in;
private ButtonGroup formatSelection;
private JCheckBox pdfFormat;
private JCheckBox jpgFormat;
private JTextField relationName;
private JTextField databaseName;
private JFileChooser fileChooser;
private JTextField dirField;
private JCheckBox subdirCB;
private JButton selectBtn;
private JButton startBtn;
private JButton stopBtn;
private JLabel progressLabel;
private Inserter inserter = null;
private void disableInput(){
pdfFormat.setEnabled(false);
jpgFormat.setEnabled(false);
relationName.setEditable(false);
databaseName.setEditable(false);
subdirCB.setEnabled(false);
selectBtn.setEnabled(false);
startBtn.setEnabled(false);
stopBtn.setEnabled(true);
progressLabel.setText("");
}
private void enableInput(){
pdfFormat.setEnabled(true);
jpgFormat.setEnabled(true);
relationName.setEditable(true);
databaseName.setEditable(true);
subdirCB.setEnabled(true);
selectBtn.setEnabled(true);
startBtn.setEnabled(true);
stopBtn.setEnabled(false);
progressLabel.setText("");
}
public void progress(int count, String name){
String text = "processed " + count + " files , current file : " + name;
progressLabel.setText(text);
}
public void finished(){
progressLabel.setText("");
enableInput();
inserter = null;
}
public PDFRelCreator(){
setSize(680,420);
Frame mainFrame = VC==null?null:VC.getMainFrame();
setLayout(new GridLayout(7,1));
formatSelection = new ButtonGroup();
pdfFormat = new JCheckBox("pdf");
jpgFormat = new JCheckBox("jpg");
formatSelection.add(pdfFormat);
formatSelection.add(jpgFormat);
pdfFormat.setSelected(true);
JPanel formatPanel = new JPanel();
formatPanel.add(new JLabel("Format"));
formatPanel.add(pdfFormat);
formatPanel.add(jpgFormat);
add(formatPanel);
pdfFormat.setSelected(true);
relationName = new JTextField(30);
JPanel relNamePanel = new JPanel();
relNamePanel.add(new JLabel("Name for relation"));
relNamePanel.add(relationName);
add(relNamePanel);
databaseName = new JTextField(30);
JPanel dbNamePanel = new JPanel();
dbNamePanel.add(new JLabel("Database"));
dbNamePanel.add(databaseName);
add(dbNamePanel);
JPanel dirPanel = new JPanel();
dirPanel.add(new JLabel("Directory"));
fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File("."));
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setAcceptAllFileFilterUsed(false);
dirField = new JTextField(30);
dirField.setEditable(false);
selectBtn = new JButton("Select");
selectBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(fileChooser.showOpenDialog(PDFRelCreator.this)==JFileChooser.APPROVE_OPTION){
File f = fileChooser.getSelectedFile();
dirField.setText(f.getAbsolutePath());
}
}
});
subdirCB = new JCheckBox("Check subdirectories");
JPanel filePanel = new JPanel();
filePanel.add(new JLabel("Directory"));
filePanel.add(dirField);
filePanel.add(subdirCB);
filePanel.add(selectBtn);
add(filePanel);
JPanel startPanel = new JPanel();
startBtn = new JButton("Start");
stopBtn = new JButton("Stop");
stopBtn.setEnabled(false);
startPanel.add(startBtn);
startPanel.add(stopBtn);
add(startPanel);
startBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
PDFRelCreator.this.start(getSelectedFormat());
}
});
stopBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
PDFRelCreator.this.inserter.stop();
}
});
JPanel progressPanel = new JPanel();
progressLabel = new JLabel("");
progressPanel.add(progressLabel);
add(progressPanel);
setVisible(true);
}
boolean isChar(char c){
return (c=='_')
|| (c >='a' && c<='z')
|| (c >='A' && c<='Z');
}
boolean isCharOrDigit(char c){
return isChar(c) || ( (c>='0') && (c<='9'));
}
boolean isSymbol(String value){
if(value.length()==0) return false;
if(!isChar(value.charAt(0))){
return false;
}
for(int i=1;i<value.length();i++){
if(!isCharOrDigit(value.charAt(i))){
return false;
}
}
return true;
}
boolean checkType(ListExpr type, FORMAT format){
ListExpr expected = getRelType(format);
return expected.equals(type);
}
boolean checkTypeAsText(ListExpr theText, FORMAT format){
if(theText.listLength()!=2){
return false;
}
theText = theText.second();
if(theText.atomType()!=ListExpr.TEXT_ATOM){
return false;
}
String text = theText.textValue();
ListExpr type=ListExpr.theEmptyList();
if(type.readFromString(text)!=0){
return false;
}
return checkType(type,format);
}
String getBase64(String fileName){
try{
BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(fileName)));
Base64Encoder encoder = new Base64Encoder(in);
int r;
StringBuffer res=new StringBuffer();
while( (r = encoder.getNext()) > -1){
char c = (char) r;
res.append(c);
}
in.close();
return res.toString();
} catch(Exception e){
return null;
}
}
private class Inserter implements Runnable{
public Inserter(File f, boolean includeSubdirs,
FORMAT format, String relName,
ViewerControl vc,
ProgressListener progressListener){
this.f = f;
this.sd = includeSubdirs;
this.progressListener = progressListener;
this.format = format;
this.relName = relName;
this.VC = vc;
}
@Override public void run(){
Stack<File> stack = new Stack<File>();
File[] files = f.listFiles();
insertFiles(stack,files,sd, format);
int length = f.getAbsolutePath().length()+1;
int count = 0;
stop = false;
while(!stack.empty() && !stop){
File top = stack.pop();
if(top.isDirectory()){
if(sd){
insertFiles(stack, top.listFiles(),sd, format);
}
} else {
String name = top.getAbsolutePath();
if(name.startsWith(f.getAbsolutePath())){
name = name.substring(length);
System.out.println("insert file " + name + " of size " + top.length() + " bytes");
String content = getBase64(top.getAbsolutePath());
if(content!=null){
name = name.replace("'"," ");
String shortName = (new File(name)).getName();
if(shortName.length()>47){
shortName = shortName.substring(shortName.length()-47);
}
String v = getConstValue(format, shortName, content);
String cmd = "query " + relName +
" inserttuple[ [const text value '"+name+"'] ,"
+ v +"] count";
VC.execCommand(cmd,errorCode, resultList, errorMessage);
if(errorCode.value != 0){
JOptionPane.showMessageDialog(null, "Problem relation update\n" + errorMessage);
System.out.println("name = " + name);
return;
} else {
count++;
progressListener.progress(count, top.getName());
}
} else {
System.err.println("problem in reading file " + top);
}
}
}
}
JOptionPane.showMessageDialog(null, "Inserted " + count + " files");
progressListener.finished();
}
public void stop(){
stop = true;
}
private void insertFiles(Stack<File> stack, File[] files, boolean sd, FORMAT format){
String ext = getExtension(format);
for(int i=0;i<files.length;i++){
if(files[i].isDirectory()) {
if(sd){
if( !files[i].getName().equals(".")
&& !files[i].getName().equals("..")){
stack.push(files[i]);
}
}
} else {
String name = files[i].getName().toLowerCase();
if(name.endsWith(ext)){
stack.push(files[i]);
}
}
}
}
private File f;
private boolean sd;
private ProgressListener progressListener;
private FORMAT format;
private String relName;
private ViewerControl VC;
private boolean stop;
}
void start( FORMAT format){
if(VC==null){
JOptionPane.showMessageDialog(this, "Internal error, ViewerControl not set");
return;
}
// check whether relation already exists and have the correct type
String relName = relationName.getText().trim();
if(!isSymbol(relName)){
JOptionPane.showMessageDialog(this, "Invalid Name for relation");
return;
}
String cmd = "";
String db = databaseName.getText().trim();
if(db.length()>0){
if(!isSymbol(db)){
JOptionPane.showMessageDialog(this, "Invalid Name for database");
return;
}
cmd = "close database "; // ignore error, may be no db open
resultList = VC.getCommandResult(cmd);
cmd = "create database " + db; // ignore error, may be database exists
resultList = VC.getCommandResult(cmd);
resultList = new ListExpr();
cmd = "open database " + db;
if(!VC.execCommand(cmd,errorCode,resultList,errorMessage)){
JOptionPane.showMessageDialog(this, "problem in opening database "+db+"\n"+ errorMessage);
return;
}
}
File f = fileChooser.getSelectedFile();
if(f==null || !f.isDirectory()){
JOptionPane.showMessageDialog(this, "No directory selected");
return;
}
cmd = "query "+ relName + " getTypeNL ";
VC.execCommand(cmd,errorCode, resultList, errorMessage);
boolean present = false;
ListExpr noP = ListExpr.twoElemList( ListExpr.symbolAtom("text"),
ListExpr.textAtom(relName));
if(errorCode.value == 0){
if(!noP.equals(resultList)){
present = true;
}
if(present){
if(!checkTypeAsText(resultList,format)){
JOptionPane.showMessageDialog(this, "Relation exists with different schema");
return;
} else {
if(JOptionPane.showConfirmDialog(this, "Relation exists, append files?")!=JOptionPane.YES_OPTION){
return;
}
}
}
}
if(!present){ // create new Relation
cmd = "let " + relName + " = " + emptyRelString(format);
VC.execCommand(cmd, errorCode, resultList , errorMessage);
if(errorCode.value != 0){
JOptionPane.showMessageDialog(this, "Problem in creating relation\n" + errorMessage);
return;
}
}
boolean sd = subdirCB.isSelected();
inserter = new Inserter(f,sd,format,relName,VC,this);
disableInput();
Thread t = new Thread(inserter);
t.start();
}
// some dummy implementations to work as an SecondoViewer
// because this viewer display nothing, these methods do
// no senseful things
public boolean selectObject(SecondoObject O){
return false;
}
public boolean isDisplayed(SecondoObject o){
return false;
}
public boolean canDisplay(SecondoObject o){
return false;
}
public void removeAll(){
}
public void removeObject(SecondoObject o){
}
public boolean addObject(SecondoObject o){
return false;
}
public String getName(){
return "PDF-JPG-Relation-Creator";
}
/* format depending parts */
private String getExtension(FORMAT format){
switch(format){
case PDF : return ".pdf";
case JPG : return ".jpg";
}
return null;
}
ListExpr getRelType(FORMAT format){
ListExpr attrList;
if(format==FORMAT.PDF){
attrList = ListExpr.twoElemList(
ListExpr.twoElemList(
ListExpr.symbolAtom("File"),
ListExpr.symbolAtom("text")),
ListExpr.twoElemList(
ListExpr.symbolAtom("Content"),
ListExpr.twoElemList(
ListExpr.symbolAtom("document"),
ListExpr.symbolAtom("pdf"))));
} else if(format==FORMAT.JPG){
attrList = ListExpr.twoElemList(
ListExpr.twoElemList(
ListExpr.symbolAtom("File"),
ListExpr.symbolAtom("text")),
ListExpr.twoElemList(
ListExpr.symbolAtom("Image"),
ListExpr.symbolAtom("picture")));
} else {
Reporter.showError("invalid Format detected, internal error");
return ListExpr.theEmptyList();
}
return ListExpr.twoElemList(
ListExpr.symbolAtom("rel"),
ListExpr.twoElemList(
ListExpr.symbolAtom("tuple"),
attrList));
}
private FORMAT getSelectedFormat(){
if(pdfFormat.isSelected()){
return FORMAT.PDF;
}
if(jpgFormat.isSelected()){
return FORMAT.JPG;
}
return null;
}
private String emptyRelString(FORMAT format){
switch(format){
case PDF : return " [const rel(tuple([File : text, Content : document(pdf)])) value ()]";
case JPG : return " [const rel(tuple([File : text, Image : picture])) value ()]";
}
return null;
}
private String getConstValue(FORMAT format, String fileName, String content){
if(format.equals(FORMAT.PDF)){
return "[const document(pdf) value '"+content+"']";
}
if(format.equals(FORMAT.JPG)){
String port = "auto";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
String date = formatter.format(new Date());
return "[const picture value (\"" + fileName +"\" \""+date+"\" \"misc\" "+port+" '"+content+"')]";
}
return null;
}
}