mirror of
https://github.com/Steffo99/unimore-oop-2020-cleaver.git
synced 2024-11-22 16:14:18 +00:00
I have done enough for tonight
This commit is contained in:
parent
b90693550a
commit
1c46967d58
29 changed files with 334 additions and 425 deletions
|
@ -4,11 +4,9 @@ import eu.steffo.cleaver.gui.panels.rows.CreateJobButtonRow;
|
||||||
import eu.steffo.cleaver.gui.panels.rows.option.CompressRow;
|
import eu.steffo.cleaver.gui.panels.rows.option.CompressRow;
|
||||||
import eu.steffo.cleaver.gui.panels.rows.option.CryptRow;
|
import eu.steffo.cleaver.gui.panels.rows.option.CryptRow;
|
||||||
import eu.steffo.cleaver.gui.panels.rows.option.SplitRow;
|
import eu.steffo.cleaver.gui.panels.rows.option.SplitRow;
|
||||||
|
import eu.steffo.cleaver.logic.config.*;
|
||||||
import eu.steffo.cleaver.logic.job.ChopJob;
|
import eu.steffo.cleaver.logic.job.ChopJob;
|
||||||
import eu.steffo.cleaver.logic.job.Job;
|
import eu.steffo.cleaver.logic.job.Job;
|
||||||
import eu.steffo.cleaver.logic.config.CompressConfig;
|
|
||||||
import eu.steffo.cleaver.logic.config.CryptConfig;
|
|
||||||
import eu.steffo.cleaver.logic.config.SplitConfig;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
@ -85,7 +83,7 @@ public class ChopPanel extends CreateJobPanel {
|
||||||
}
|
}
|
||||||
for(File file : fileSelectPanel.getSelectedFiles()) {
|
for(File file : fileSelectPanel.getSelectedFiles()) {
|
||||||
|
|
||||||
SplitConfig sc;
|
ISplitConfig sc;
|
||||||
try {
|
try {
|
||||||
sc = splitRow.getSplitConfig(file.length());
|
sc = splitRow.getSplitConfig(file.length());
|
||||||
} catch (NumberFormatException exc) {
|
} catch (NumberFormatException exc) {
|
||||||
|
@ -93,9 +91,9 @@ public class ChopPanel extends CreateJobPanel {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptConfig cc = cryptRow.getCryptConfig();
|
ICryptConfig cc = cryptRow.getCryptConfig();
|
||||||
|
|
||||||
CompressConfig zc = compressRow.getCompressConfig();
|
ICompressConfig zc = compressRow.getCompressConfig();
|
||||||
|
|
||||||
Job job = new ChopJob(file, sc, cc, zc, onProgressChange);
|
Job job = new ChopJob(file, sc, cc, zc, onProgressChange);
|
||||||
jobs.add(job);
|
jobs.add(job);
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package eu.steffo.cleaver.gui.panels;
|
package eu.steffo.cleaver.gui.panels;
|
||||||
|
|
||||||
|
import eu.steffo.cleaver.logic.config.*;
|
||||||
import eu.steffo.cleaver.logic.job.Job;
|
import eu.steffo.cleaver.logic.job.Job;
|
||||||
import eu.steffo.cleaver.logic.config.CompressConfig;
|
|
||||||
import eu.steffo.cleaver.logic.config.CryptConfig;
|
|
||||||
import eu.steffo.cleaver.logic.config.SplitConfig;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
@ -82,15 +80,15 @@ public class JobsTablePanel extends JPanel {
|
||||||
case 1:
|
case 1:
|
||||||
return job.getFile().getAbsolutePath();
|
return job.getFile().getAbsolutePath();
|
||||||
case 2:
|
case 2:
|
||||||
SplitConfig s = job.getSplitConfig();
|
ISplitConfig s = job.getSplitConfig();
|
||||||
if(s == null) return "";
|
if(s == null) return "";
|
||||||
return s.toString();
|
return s.toString();
|
||||||
case 3:
|
case 3:
|
||||||
CryptConfig k = job.getCryptConfig();
|
ICryptConfig k = job.getCryptConfig();
|
||||||
if(k == null) return "";
|
if(k == null) return "";
|
||||||
return k.toString();
|
return k.toString();
|
||||||
case 4:
|
case 4:
|
||||||
CompressConfig c = job.getCompressConfig();
|
ICompressConfig c = job.getCompressConfig();
|
||||||
if(c == null) return "";
|
if(c == null) return "";
|
||||||
return c.toString();
|
return c.toString();
|
||||||
case 5:
|
case 5:
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package eu.steffo.cleaver.gui.panels.rows.option;
|
package eu.steffo.cleaver.gui.panels.rows.option;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.config.CompressConfig;
|
import eu.steffo.cleaver.logic.config.DeflateConfig;
|
||||||
|
import eu.steffo.cleaver.logic.config.ICompressConfig;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link OptionRow} allowing the {@link CompressConfig configuration of the compress step} of the file chop process.
|
* A {@link OptionRow} allowing the {@link DeflateConfig configuration of the compress step} of the file chop process.
|
||||||
*
|
*
|
||||||
* @see eu.steffo.cleaver.gui.panels.ChopPanel
|
* @see eu.steffo.cleaver.gui.panels.ChopPanel
|
||||||
*/
|
*/
|
||||||
|
@ -32,17 +33,17 @@ public class CompressRow extends OptionRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link CompressConfig} from the settings in this {@link OptionRow}.
|
* Create a {@link DeflateConfig} from the settings in this {@link OptionRow}.
|
||||||
* @return The resulting {@link CompressConfig}, or {@literal null} if the {@link #compressionCheckBox} is unticked.
|
* @return The resulting {@link DeflateConfig}, or {@literal null} if the {@link #compressionCheckBox} is unticked.
|
||||||
*/
|
*/
|
||||||
public CompressConfig getCompressConfig() {
|
public ICompressConfig getCompressConfig() {
|
||||||
if(!compressionCheckBox.isSelected()) {
|
if(!compressionCheckBox.isSelected()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new CompressConfig();
|
return new DeflateConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCompressConfig(CompressConfig cfg) {
|
public void setCompressConfig(DeflateConfig cfg) {
|
||||||
if(cfg == null) {
|
if(cfg == null) {
|
||||||
compressionCheckBox.setSelected(false);
|
compressionCheckBox.setSelected(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package eu.steffo.cleaver.gui.panels.rows.option;
|
package eu.steffo.cleaver.gui.panels.rows.option;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.config.CryptConfig;
|
import eu.steffo.cleaver.logic.config.PasswordConfig;
|
||||||
|
import eu.steffo.cleaver.logic.config.ICryptConfig;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link OptionRow} allowing the {@link CryptConfig configuration of the crypt step} of the file chop process.
|
* A {@link OptionRow} allowing the {@link PasswordConfig configuration of the crypt step} of the file chop process.
|
||||||
*
|
*
|
||||||
* @see eu.steffo.cleaver.gui.panels.ChopPanel
|
* @see eu.steffo.cleaver.gui.panels.ChopPanel
|
||||||
*/
|
*/
|
||||||
|
@ -65,14 +66,14 @@ public class CryptRow extends OptionRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link CryptConfig} from the settings in this {@link OptionRow}.
|
* Create a {@link PasswordConfig} from the settings in this {@link OptionRow}.
|
||||||
* @return The resulting {@link CryptConfig}, or {@literal null} if the {@link #cryptCheckBox} is unticked.
|
* @return The resulting {@link PasswordConfig}, or {@literal null} if the {@link #cryptCheckBox} is unticked.
|
||||||
*/
|
*/
|
||||||
public CryptConfig getCryptConfig() {
|
public ICryptConfig getCryptConfig() {
|
||||||
if(!cryptCheckBox.isSelected()) {
|
if(!cryptCheckBox.isSelected()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new CryptConfig(keyTextField.getText());
|
return new PasswordConfig(keyTextField.getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package eu.steffo.cleaver.gui.panels.rows.option;
|
package eu.steffo.cleaver.gui.panels.rows.option;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.config.CryptConfig;
|
import eu.steffo.cleaver.logic.config.PasswordConfig;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link OptionRow} allowing the {@link CryptConfig configuration of the crypt step} of the file stitch process.
|
* A {@link OptionRow} allowing the {@link PasswordConfig configuration of the crypt step} of the file stitch process.
|
||||||
*
|
*
|
||||||
* This configuration is used only if the selected *.chp file specifies that the *.cXX are encrypted.
|
* This configuration is used only if the selected *.chp file specifies that the *.cXX are encrypted.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
package eu.steffo.cleaver.gui.panels.rows.option;
|
package eu.steffo.cleaver.gui.panels.rows.option;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.config.SplitByPartsConfig;
|
import eu.steffo.cleaver.logic.config.PartsConfig;
|
||||||
import eu.steffo.cleaver.logic.config.SplitBySizeConfig;
|
import eu.steffo.cleaver.logic.config.ISplitConfig;
|
||||||
import eu.steffo.cleaver.logic.config.SplitConfig;
|
import eu.steffo.cleaver.logic.config.SizeConfig;
|
||||||
|
import eu.steffo.cleaver.logic.config.IConfig;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.DocumentEvent;
|
import javax.swing.event.DocumentEvent;
|
||||||
import javax.swing.event.DocumentListener;
|
import javax.swing.event.DocumentListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link OptionRow} allowing the {@link SplitConfig configuration of the split step} of the file chop process.
|
* A {@link OptionRow} allowing the {@link IConfig configuration of the split step} of the file chop process.
|
||||||
*
|
*
|
||||||
* @see eu.steffo.cleaver.gui.panels.ChopPanel
|
* @see eu.steffo.cleaver.gui.panels.ChopPanel
|
||||||
*/
|
*/
|
||||||
|
@ -149,19 +150,19 @@ public class SplitRow extends OptionRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link SplitConfig} from the settings in this {@link OptionRow}.
|
* Create a {@link IConfig} from the settings in this {@link OptionRow}.
|
||||||
* @param fileSize The size of the file that the {@link SplitConfig} is being generated for.
|
* @param fileSize The size of the file that the {@link IConfig} is being generated for.
|
||||||
* @return The resulting {@link SplitConfig}, or {@literal null} if the {@link #splitCheckBox} is unticked.
|
* @return The resulting {@link IConfig}, or {@literal null} if the {@link #splitCheckBox} is unticked.
|
||||||
*/
|
*/
|
||||||
public SplitConfig getSplitConfig(long fileSize) throws NumberFormatException {
|
public ISplitConfig getSplitConfig(long fileSize) throws NumberFormatException {
|
||||||
if(!splitCheckBox.isSelected()) {
|
if(!splitCheckBox.isSelected()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else if(!sizeTextField.getText().equals("")) {
|
else if(!sizeTextField.getText().equals("")) {
|
||||||
return new SplitBySizeConfig(Integer.parseInt(sizeTextField.getText()), fileSize);
|
return new SizeConfig(Long.parseLong(sizeTextField.getText()));
|
||||||
}
|
}
|
||||||
else if(!partsTextField.getText().equals("")) {
|
else if(!partsTextField.getText().equals("")) {
|
||||||
return new SplitByPartsConfig(Integer.parseInt(partsTextField.getText()), fileSize);
|
return new PartsConfig(Integer.parseInt(partsTextField.getText()));
|
||||||
}
|
}
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package eu.steffo.cleaver.logic.config;
|
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.job.Job;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class containing the configuration for the compression step of a {@link Job Job}.
|
|
||||||
*/
|
|
||||||
public class CompressConfig {
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Yes (Deflate)";
|
|
||||||
}
|
|
||||||
}
|
|
11
src/eu/steffo/cleaver/logic/config/DeflateConfig.java
Normal file
11
src/eu/steffo/cleaver/logic/config/DeflateConfig.java
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link IConfig} for compressing a file with the <a href="https://en.wikipedia.org/wiki/DEFLATE">Deflate</a> algorithm.
|
||||||
|
*/
|
||||||
|
public class DeflateConfig implements ICompressConfig {
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Yes (Deflate)";
|
||||||
|
}
|
||||||
|
}
|
7
src/eu/steffo/cleaver/logic/config/ICompressConfig.java
Normal file
7
src/eu/steffo/cleaver/logic/config/ICompressConfig.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link IConfig} for the Compress step of the {@link eu.steffo.cleaver.logic.job.ChopJob Chop}/{@link eu.steffo.cleaver.logic.job.StitchJob Stitch} process.
|
||||||
|
*/
|
||||||
|
public interface ICompressConfig extends IConfig {
|
||||||
|
}
|
14
src/eu/steffo/cleaver/logic/config/IConfig.java
Normal file
14
src/eu/steffo/cleaver/logic/config/IConfig.java
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
|
import eu.steffo.cleaver.logic.job.Job;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for the configuration of a step of a {@link Job Job}.
|
||||||
|
*/
|
||||||
|
public interface IConfig {
|
||||||
|
/**
|
||||||
|
* @return The string representation of the {@link IConfig}, to be used in the jobs table.
|
||||||
|
* @see eu.steffo.cleaver.gui.panels.JobsTablePanel
|
||||||
|
*/
|
||||||
|
String toString();
|
||||||
|
}
|
7
src/eu/steffo/cleaver/logic/config/ICryptConfig.java
Normal file
7
src/eu/steffo/cleaver/logic/config/ICryptConfig.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link IConfig} for the Crypt step of the {@link eu.steffo.cleaver.logic.job.ChopJob Chop}/{@link eu.steffo.cleaver.logic.job.StitchJob Stitch} process.
|
||||||
|
*/
|
||||||
|
public interface ICryptConfig extends IConfig {
|
||||||
|
}
|
7
src/eu/steffo/cleaver/logic/config/ISplitConfig.java
Normal file
7
src/eu/steffo/cleaver/logic/config/ISplitConfig.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link IConfig} for the Split step of the {@link eu.steffo.cleaver.logic.job.ChopJob Chop}/{@link eu.steffo.cleaver.logic.job.StitchJob Stitch} process.
|
||||||
|
*/
|
||||||
|
public interface ISplitConfig extends IConfig {
|
||||||
|
}
|
|
@ -1,53 +0,0 @@
|
||||||
package eu.steffo.cleaver.logic.config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link SplitConfig} created by reading a *.chp file, containing the number of parts and their size, but not the resulting file size.
|
|
||||||
*/
|
|
||||||
public class MergeConfig extends SplitConfig {
|
|
||||||
/**
|
|
||||||
* The size of the parts the file was split in.
|
|
||||||
*/
|
|
||||||
private long partSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of parts the file was split in.
|
|
||||||
*/
|
|
||||||
private int parts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The total size of the original file.
|
|
||||||
*/
|
|
||||||
private long totalSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new MergeConfig.
|
|
||||||
* @param partSize The size of the parts the file was split in.
|
|
||||||
* @param parts The number of parts the file was split in.
|
|
||||||
* @param totalSize The total size of the original file.
|
|
||||||
*/
|
|
||||||
public MergeConfig(long partSize, int parts, long totalSize) {
|
|
||||||
this.partSize = partSize;
|
|
||||||
this.parts = parts;
|
|
||||||
this.totalSize = totalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getPartSize() {
|
|
||||||
return partSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPartCount() {
|
|
||||||
return parts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalSize() {
|
|
||||||
return totalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.format("%d parts (%d bytes)", parts, partSize);
|
|
||||||
}
|
|
||||||
}
|
|
28
src/eu/steffo/cleaver/logic/config/PartsConfig.java
Normal file
28
src/eu/steffo/cleaver/logic/config/PartsConfig.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link IConfig} for splitting a file in a specific number of parts.
|
||||||
|
*/
|
||||||
|
public class PartsConfig implements ISplitConfig {
|
||||||
|
/**
|
||||||
|
* The number of parts the file should be split in.
|
||||||
|
*/
|
||||||
|
private int parts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new SplitByPartsConfig.
|
||||||
|
* @param parts The number of parts the file should be split in.
|
||||||
|
*/
|
||||||
|
public PartsConfig(int parts) {
|
||||||
|
this.parts = parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%d parts", this.parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPartCount() {
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,16 @@
|
||||||
package eu.steffo.cleaver.logic.config;
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.job.Job;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class containing the configuration for the encryption/decryption step of a {@link Job Job}.
|
* A config for encrypting a file with an arbitrary length password.
|
||||||
*/
|
*/
|
||||||
public class CryptConfig {
|
public class PasswordConfig implements ICryptConfig {
|
||||||
protected final String key;
|
protected final String key;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new CryptConfig with a specific encryption key.
|
* Construct a new CryptConfig with a specific encryption key.
|
||||||
* @param key The encryption key.
|
* @param key The encryption key.
|
||||||
*/
|
*/
|
||||||
public CryptConfig(String key) {
|
public PasswordConfig(String key) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
28
src/eu/steffo/cleaver/logic/config/SizeConfig.java
Normal file
28
src/eu/steffo/cleaver/logic/config/SizeConfig.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link IConfig} for splitting a file in parts of a specific part size.
|
||||||
|
*/
|
||||||
|
public class SizeConfig implements ISplitConfig {
|
||||||
|
/**
|
||||||
|
* The size of the parts to split the file in.
|
||||||
|
*/
|
||||||
|
private long partSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new SplitBySizeConfig.
|
||||||
|
* @param partSize The size of the parts to split the file in.
|
||||||
|
*/
|
||||||
|
public SizeConfig(long partSize) {
|
||||||
|
this.partSize = partSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%d bytes", this.partSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPartSize() {
|
||||||
|
return partSize;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,43 +0,0 @@
|
||||||
package eu.steffo.cleaver.logic.config;
|
|
||||||
|
|
||||||
public class SplitByPartsConfig extends SplitConfig {
|
|
||||||
/**
|
|
||||||
* The number of parts the file should be split in.
|
|
||||||
*/
|
|
||||||
private int parts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The total size of the file to split.
|
|
||||||
*/
|
|
||||||
private long totalSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new SplitByPartsConfig.
|
|
||||||
* @param parts The number of parts the file should be split in.
|
|
||||||
* @param totalSize The total size of the file to split.
|
|
||||||
*/
|
|
||||||
public SplitByPartsConfig(int parts, long totalSize) {
|
|
||||||
this.parts = parts;
|
|
||||||
this.totalSize = totalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.format("%d parts", this.parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getPartSize() {
|
|
||||||
return (int)Math.ceil((double) totalSize / (double)parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPartCount() {
|
|
||||||
return parts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalSize() {
|
|
||||||
return totalSize;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package eu.steffo.cleaver.logic.config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link SplitConfig} for splitting a file in parts of a specific part size.
|
|
||||||
*/
|
|
||||||
public class SplitBySizeConfig extends SplitConfig {
|
|
||||||
/**
|
|
||||||
* The size of the parts to split the file in.
|
|
||||||
*/
|
|
||||||
private long partSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The total size of the file to split.
|
|
||||||
*/
|
|
||||||
private long totalSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new SplitBySizeConfig.
|
|
||||||
* @param partSize The size of the parts to split the file in.
|
|
||||||
* @param totalSize The total size of the file to split.
|
|
||||||
*/
|
|
||||||
public SplitBySizeConfig(long partSize, long totalSize) {
|
|
||||||
this.partSize = partSize;
|
|
||||||
this.totalSize = totalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.format("%d bytes", this.partSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getPartSize() {
|
|
||||||
return partSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPartCount() {
|
|
||||||
return (int)Math.ceil((double) totalSize / (double)partSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalSize() {
|
|
||||||
return totalSize;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package eu.steffo.cleaver.logic.config;
|
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.job.Job;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class containing the configuration for the split/merge step of a {@link Job Job}.
|
|
||||||
*/
|
|
||||||
public abstract class SplitConfig {
|
|
||||||
/**
|
|
||||||
* @return The size in bytes of a single part of the file.
|
|
||||||
*/
|
|
||||||
public abstract long getPartSize();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The number of parts the file should be split in.
|
|
||||||
*/
|
|
||||||
public abstract int getPartCount();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The total size of the original file.
|
|
||||||
*/
|
|
||||||
public abstract long getTotalSize();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The string representation of the {@link SplitConfig}, to be used in the jobs table.
|
|
||||||
* @see eu.steffo.cleaver.gui.panels.JobsTablePanel
|
|
||||||
*/
|
|
||||||
public abstract String toString();
|
|
||||||
}
|
|
|
@ -1,15 +1,12 @@
|
||||||
package eu.steffo.cleaver.logic.job;
|
package eu.steffo.cleaver.logic.job;
|
||||||
|
|
||||||
import eu.steffo.cleaver.errors.ProgrammingError;
|
import eu.steffo.cleaver.errors.ProgrammingError;
|
||||||
import eu.steffo.cleaver.logic.config.CompressConfig;
|
import eu.steffo.cleaver.logic.config.*;
|
||||||
import eu.steffo.cleaver.logic.config.CryptConfig;
|
import eu.steffo.cleaver.logic.stream.output.*;
|
||||||
import eu.steffo.cleaver.logic.stream.output.CleaverCryptOutputStream;
|
|
||||||
import eu.steffo.cleaver.logic.progress.ErrorProgress;
|
import eu.steffo.cleaver.logic.progress.ErrorProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.FinishedProgress;
|
import eu.steffo.cleaver.logic.progress.FinishedProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.Progress;
|
import eu.steffo.cleaver.logic.progress.Progress;
|
||||||
import eu.steffo.cleaver.logic.progress.WorkingProgress;
|
import eu.steffo.cleaver.logic.progress.WorkingProgress;
|
||||||
import eu.steffo.cleaver.logic.config.SplitConfig;
|
|
||||||
import eu.steffo.cleaver.logic.stream.output.CleaverSplitFileOutputStream;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
@ -21,7 +18,6 @@ import javax.xml.transform.TransformerFactory;
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.zip.DeflaterOutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Job} that converts regular files into <i>chopped</i> (*.chp + *.cXX) files.
|
* A {@link Job} that converts regular files into <i>chopped</i> (*.chp + *.cXX) files.
|
||||||
|
@ -29,20 +25,20 @@ import java.util.zip.DeflaterOutputStream;
|
||||||
public class ChopJob extends Job {
|
public class ChopJob extends Job {
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
private final SplitConfig splitConfig;
|
private final ISplitConfig splitConfig;
|
||||||
private final CryptConfig cryptConfig;
|
private final ICryptConfig cryptConfig;
|
||||||
private final CompressConfig compressConfig;
|
private final ICompressConfig compressConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ChopJob (with progress updates support).
|
* Create a new ChopJob (with progress updates support).
|
||||||
* @param file The file to be chopped.
|
* @param file The file to be chopped.
|
||||||
* @param splitConfig The configuration for the split step.
|
* @param splitConfig The configuration for the Split step.
|
||||||
* @param cryptConfig The configuration for the crypt step.
|
* @param cryptConfig The configuration for the Crypt step.
|
||||||
* @param compressConfig The configuration for the compress step.
|
* @param compressConfig The configuration for the Compress step.
|
||||||
* @param onProgressChange A {@link Runnable} that should be invoked when {@link #setProgress(Progress)} is called.
|
* @param onProgressChange A {@link Runnable} that should be invoked when {@link #setProgress(Progress)} is called.
|
||||||
* @see Job#Job(Runnable)
|
* @see Job#Job(Runnable)
|
||||||
*/
|
*/
|
||||||
public ChopJob(File file, SplitConfig splitConfig, CryptConfig cryptConfig, CompressConfig compressConfig, Runnable onProgressChange) {
|
public ChopJob(File file, ISplitConfig splitConfig, ICryptConfig cryptConfig, ICompressConfig compressConfig, Runnable onProgressChange) {
|
||||||
super(onProgressChange);
|
super(onProgressChange);
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.splitConfig = splitConfig;
|
this.splitConfig = splitConfig;
|
||||||
|
@ -53,13 +49,13 @@ public class ChopJob extends Job {
|
||||||
/**
|
/**
|
||||||
* Create a new ChopJob (without progress updates support).
|
* Create a new ChopJob (without progress updates support).
|
||||||
* @param file The file to be chopped.
|
* @param file The file to be chopped.
|
||||||
* @param splitConfig The configuration for the split step.
|
* @param splitConfig The configuration for the Split step.
|
||||||
* @param cryptConfig The configuration for the crypt step.
|
* @param cryptConfig The configuration for the Crypt step.
|
||||||
* @param compressConfig The configuration for the compress step.
|
* @param compressConfig The configuration for the Compress step.
|
||||||
* @see ChopJob#ChopJob(File, SplitConfig, CryptConfig, CompressConfig, Runnable)
|
* @see ChopJob#ChopJob(File, ISplitConfig, ICryptConfig, ICompressConfig, Runnable)
|
||||||
* @see Job#Job()
|
* @see Job#Job()
|
||||||
*/
|
*/
|
||||||
public ChopJob(File file, SplitConfig splitConfig, CryptConfig cryptConfig, CompressConfig compressConfig) {
|
public ChopJob(File file, ISplitConfig splitConfig, ICryptConfig cryptConfig, ICompressConfig compressConfig) {
|
||||||
this(file, splitConfig, cryptConfig, compressConfig, null);
|
this(file, splitConfig, cryptConfig, compressConfig, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,17 +70,17 @@ public class ChopJob extends Job {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SplitConfig getSplitConfig() {
|
public ISplitConfig getSplitConfig() {
|
||||||
return splitConfig;
|
return splitConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CryptConfig getCryptConfig() {
|
public ICryptConfig getCryptConfig() {
|
||||||
return cryptConfig;
|
return cryptConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompressConfig getCompressConfig() {
|
public ICompressConfig getCompressConfig() {
|
||||||
return compressConfig;
|
return compressConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,19 +90,22 @@ public class ChopJob extends Job {
|
||||||
InputStream inputStream = new FileInputStream(file);
|
InputStream inputStream = new FileInputStream(file);
|
||||||
OutputStream outputStream;
|
OutputStream outputStream;
|
||||||
|
|
||||||
if(splitConfig != null) {
|
if(splitConfig instanceof SizeConfig) {
|
||||||
outputStream = new CleaverSplitFileOutputStream(file.getAbsolutePath(), splitConfig.getPartSize());
|
outputStream = new CleaverSplitFileOutputStream(file.getAbsolutePath(), ((SizeConfig)splitConfig).getPartSize());
|
||||||
|
}
|
||||||
|
else if(splitConfig instanceof PartsConfig) {
|
||||||
|
outputStream = new CleaverForkFileOutputStream(file.getAbsolutePath(), ((PartsConfig)splitConfig).getPartCount());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outputStream = new FileOutputStream(String.format("%s.c0", file.getAbsolutePath()));
|
outputStream = new CleaverSimpleFileOutputStream(file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(compressConfig != null) {
|
if(compressConfig instanceof DeflateConfig) {
|
||||||
outputStream = new DeflaterOutputStream(outputStream);
|
outputStream = new CleaverDeflaterOutputStream(outputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cryptConfig != null) {
|
if(cryptConfig instanceof PasswordConfig) {
|
||||||
outputStream = new CleaverCryptOutputStream(outputStream, cryptConfig.getKey());
|
outputStream = new CleaverCryptOutputStream(outputStream, ((PasswordConfig)cryptConfig).getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create the .chp file
|
//Create the .chp file
|
||||||
|
@ -121,26 +120,6 @@ public class ChopJob extends Job {
|
||||||
Element root = doc.createElement("Cleaver");
|
Element root = doc.createElement("Cleaver");
|
||||||
doc.appendChild(root);
|
doc.appendChild(root);
|
||||||
|
|
||||||
Element original = doc.createElement("Original");
|
|
||||||
original.setTextContent(file.getName());
|
|
||||||
root.appendChild(original);
|
|
||||||
|
|
||||||
if(splitConfig != null) {
|
|
||||||
root.appendChild(splitConfig.toElement(doc));
|
|
||||||
}
|
|
||||||
if(compressConfig != null) {
|
|
||||||
root.appendChild(compressConfig.toElement(doc));
|
|
||||||
}
|
|
||||||
if(cryptConfig != null) {
|
|
||||||
root.appendChild(cryptConfig.toElement(doc));
|
|
||||||
}
|
|
||||||
|
|
||||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
|
||||||
Transformer transformer = transformerFactory.newTransformer();
|
|
||||||
DOMSource source = new DOMSource(doc);
|
|
||||||
StreamResult result = new StreamResult(String.format("%s.chp", file.getAbsolutePath()));
|
|
||||||
transformer.transform(source, result);
|
|
||||||
|
|
||||||
//Pipe everything to the output
|
//Pipe everything to the output
|
||||||
int bytesUntilNextUpdate = 2048;
|
int bytesUntilNextUpdate = 2048;
|
||||||
this.setProgress(new WorkingProgress());
|
this.setProgress(new WorkingProgress());
|
||||||
|
@ -158,6 +137,14 @@ public class ChopJob extends Job {
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
|
|
||||||
|
root.appendChild(((ICleaverOutputStream)outputStream).toElement(doc));
|
||||||
|
|
||||||
|
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
|
Transformer transformer = transformerFactory.newTransformer();
|
||||||
|
DOMSource source = new DOMSource(doc);
|
||||||
|
StreamResult result = new StreamResult(String.format("%s.chp", file.getAbsolutePath()));
|
||||||
|
transformer.transform(source, result);
|
||||||
|
|
||||||
this.setProgress(new FinishedProgress());
|
this.setProgress(new FinishedProgress());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -3,11 +3,9 @@ package eu.steffo.cleaver.logic.job;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.config.CompressConfig;
|
import eu.steffo.cleaver.logic.config.*;
|
||||||
import eu.steffo.cleaver.logic.config.CryptConfig;
|
|
||||||
import eu.steffo.cleaver.logic.progress.NotStartedProgress;
|
import eu.steffo.cleaver.logic.progress.NotStartedProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.Progress;
|
import eu.steffo.cleaver.logic.progress.Progress;
|
||||||
import eu.steffo.cleaver.logic.config.SplitConfig;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Thread} that allows access to the basic .
|
* A {@link Thread} that allows access to the basic .
|
||||||
|
@ -62,19 +60,19 @@ public abstract class Job extends Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The {@link SplitConfig} of the job. If {@literal null}, the job shouldn't handle file splitting/merging.
|
* @return The {@link IConfig} for the Split step of the job. If {@literal null}, the job shouldn't handle file splitting/merging.
|
||||||
*/
|
*/
|
||||||
public abstract SplitConfig getSplitConfig();
|
public abstract ISplitConfig getSplitConfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The {@link CryptConfig} of the job. If {@literal null}, the job shouldn't handle file encryption/decryption.
|
* @return The {@link IConfig} for the Crypt step of the job. If {@literal null}, the job shouldn't handle file encryption/decryption.
|
||||||
*/
|
*/
|
||||||
public abstract CryptConfig getCryptConfig();
|
public abstract ICryptConfig getCryptConfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The {@link CompressConfig} of the job. If {@literal null}, the job shouldn't handle file compression/decompression.
|
* @return The {@link IConfig} for the Compress step of the job. If {@literal null}, the job shouldn't handle file compression/decompression.
|
||||||
*/
|
*/
|
||||||
public abstract CompressConfig getCompressConfig();
|
public abstract ICompressConfig getCompressConfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the progress of the job to a different value.
|
* Set the progress of the job to a different value.
|
||||||
|
|
|
@ -2,10 +2,7 @@ package eu.steffo.cleaver.logic.job;
|
||||||
|
|
||||||
import eu.steffo.cleaver.errors.ChpFileError;
|
import eu.steffo.cleaver.errors.ChpFileError;
|
||||||
import eu.steffo.cleaver.errors.ProgrammingError;
|
import eu.steffo.cleaver.errors.ProgrammingError;
|
||||||
import eu.steffo.cleaver.logic.config.CompressConfig;
|
import eu.steffo.cleaver.logic.config.*;
|
||||||
import eu.steffo.cleaver.logic.config.CryptConfig;
|
|
||||||
import eu.steffo.cleaver.logic.config.MergeConfig;
|
|
||||||
import eu.steffo.cleaver.logic.config.SplitConfig;
|
|
||||||
import eu.steffo.cleaver.logic.stream.input.CryptInputStream;
|
import eu.steffo.cleaver.logic.stream.input.CryptInputStream;
|
||||||
import eu.steffo.cleaver.logic.progress.ErrorProgress;
|
import eu.steffo.cleaver.logic.progress.ErrorProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.FinishedProgress;
|
import eu.steffo.cleaver.logic.progress.FinishedProgress;
|
||||||
|
@ -25,15 +22,16 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Job} that converts <i>chopped</i> (*.chp + *.cXX) files back into regular files.
|
* A {@link Job} that converts <i>chopped</i> (*.chp + *.cXX) files back into regular files.
|
||||||
*/
|
*/
|
||||||
public class StitchJob extends Job {
|
public class StitchJob extends Job {
|
||||||
private File resultFile;
|
private File resultFile;
|
||||||
private File chpFile;
|
private File chpFile;
|
||||||
private SplitConfig splitConfig = null;
|
private ISplitConfig splitConfig = null;
|
||||||
private CryptConfig cryptConfig = null;
|
private ICryptConfig cryptConfig = null;
|
||||||
private CompressConfig compressConfig = null;
|
private ICompressConfig compressConfig = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a StitchJob, specifying the *.chp file to import the settings from.
|
* Construct a StitchJob, specifying the *.chp file to import the settings from.
|
||||||
|
@ -84,17 +82,17 @@ public class StitchJob extends Job {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SplitConfig getSplitConfig() {
|
public ISplitConfig getSplitConfig() {
|
||||||
return splitConfig;
|
return splitConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CryptConfig getCryptConfig() {
|
public ICryptConfig getCryptConfig() {
|
||||||
return cryptConfig;
|
return cryptConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompressConfig getCompressConfig() {
|
public ICompressConfig getCompressConfig() {
|
||||||
return compressConfig;
|
return compressConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,104 +123,17 @@ public class StitchJob extends Job {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a {@link Document} and set the {@link SplitConfig}, {@link CryptConfig} and {@link CompressConfig} of this job accordingly.
|
* Read a {@link Document} and set the {@link IConfig}, {@link PasswordConfig} and {@link DeflateConfig} of this job accordingly.
|
||||||
* @param doc The {@link Document} to be read.
|
* @param doc The {@link Document} to be read.
|
||||||
* @param cryptKey The encryption key to use in the {@link CryptConfig}.
|
* @param cryptKey The encryption key to use in the {@link PasswordConfig}.
|
||||||
* @throws ChpFileError If there's an error while parsing the *.chp file.
|
* @throws ChpFileError If there's an error while parsing the *.chp file.
|
||||||
*/
|
*/
|
||||||
protected void parseChp(Document doc, String cryptKey) throws ChpFileError {
|
protected void parseChp(Document doc, String cryptKey) throws ChpFileError {
|
||||||
Element root = doc.getDocumentElement();
|
//TODO
|
||||||
|
|
||||||
NodeList originals = root.getElementsByTagName("Original");
|
|
||||||
NodeList splits = root.getElementsByTagName("Split");
|
|
||||||
NodeList crypts = root.getElementsByTagName("Crypt");
|
|
||||||
NodeList compresses = root.getElementsByTagName("Compress");
|
|
||||||
|
|
||||||
Node originalNode = originals.item(0);
|
|
||||||
Node splitNode = splits.item(0);
|
|
||||||
Node cryptNode = crypts.item(0);
|
|
||||||
Node compressNode = compresses.item(0);
|
|
||||||
|
|
||||||
if(originalNode == null) {
|
|
||||||
throw new ChpFileError("No original filename found (<Original> tag)");
|
|
||||||
}
|
|
||||||
Element original = (Element)originalNode;
|
|
||||||
//The resulting file will be in the same directory of the *.chp file
|
|
||||||
resultFile = new File(chpFile.getAbsoluteFile().getParentFile().getAbsolutePath().concat("/" + original.getTextContent()));
|
|
||||||
|
|
||||||
if(splitNode != null) {
|
|
||||||
Element split = (Element)splitNode;
|
|
||||||
|
|
||||||
long partSize;
|
|
||||||
try {
|
|
||||||
partSize = Long.parseLong(split.getAttribute("part-size"));
|
|
||||||
} catch(NumberFormatException e) {
|
|
||||||
throw new ChpFileError("Corrupt part size data.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int parts;
|
|
||||||
try {
|
|
||||||
parts = Integer.parseInt(split.getAttribute("parts"));
|
|
||||||
} catch(NumberFormatException e) {
|
|
||||||
throw new ChpFileError("Corrupt parts data.");
|
|
||||||
}
|
|
||||||
|
|
||||||
long totalSize;
|
|
||||||
try {
|
|
||||||
totalSize = Long.parseLong(split.getAttribute("total-size"));
|
|
||||||
} catch(NumberFormatException e) {
|
|
||||||
throw new ChpFileError("Corrupt total size data.");
|
|
||||||
}
|
|
||||||
|
|
||||||
splitConfig = new MergeConfig(partSize, parts, totalSize);
|
|
||||||
}
|
|
||||||
if(cryptNode != null) {
|
|
||||||
cryptConfig = new CryptConfig(cryptKey);
|
|
||||||
}
|
|
||||||
if(compressNode != null) {
|
|
||||||
compressConfig = new CompressConfig();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
//TODO
|
||||||
InputStream inputStream;
|
|
||||||
OutputStream outputStream = new FileOutputStream(resultFile);
|
|
||||||
|
|
||||||
if (splitConfig != null) {
|
|
||||||
inputStream = new CleaverSplitFileInputStream(resultFile.getPath(), splitConfig.getPartSize());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
inputStream = new FileInputStream(String.format("%s.c0", resultFile.getAbsolutePath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compressConfig != null) {
|
|
||||||
inputStream = new InflaterInputStream(inputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cryptConfig != null) {
|
|
||||||
inputStream = new CryptInputStream(inputStream, cryptConfig.getKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Pipe everything to the output
|
|
||||||
int bytesUntilNextUpdate = 2048;
|
|
||||||
this.setProgress(new WorkingProgress());
|
|
||||||
|
|
||||||
int i;
|
|
||||||
while((i = inputStream.read()) != -1) {
|
|
||||||
outputStream.write(i);
|
|
||||||
bytesUntilNextUpdate -= 1;
|
|
||||||
if(bytesUntilNextUpdate <= 0) {
|
|
||||||
this.setProgress(new WorkingProgress((float)(resultFile.length() - inputStream.available()) / (float)resultFile.length()));
|
|
||||||
bytesUntilNextUpdate = 2048;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setProgress(new FinishedProgress());
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
this.setProgress(new ErrorProgress(e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ public class CleaverCryptOutputStream extends FilterOutputStream implements ICle
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new <a href="https://en.wikipedia.org/wiki/Initialization_vector">Initialization Vector</a> with the specified size.
|
* Generate a new <a href="https://en.wikipedia.org/wiki/Initialization_vector">Initialization Vector</a> with the specified size.
|
||||||
* @param size The size of the initialization vector.
|
* @param size The size in bytes of the initialization vector.
|
||||||
* @return The generated IV.
|
* @return The generated IV.
|
||||||
*/
|
*/
|
||||||
protected IvParameterSpec generateIV(int size) {
|
protected IvParameterSpec generateIV(int size) {
|
||||||
|
@ -103,15 +103,18 @@ public class CleaverCryptOutputStream extends FilterOutputStream implements ICle
|
||||||
* @throws NoSuchAlgorithmException If the {@link #ENCRYPTION_ALGORITHM} is invalid.
|
* @throws NoSuchAlgorithmException If the {@link #ENCRYPTION_ALGORITHM} is invalid.
|
||||||
* @throws InvalidKeySpecException If the generated {@link KeySpec} is invalid.
|
* @throws InvalidKeySpecException If the generated {@link KeySpec} is invalid.
|
||||||
*/
|
*/
|
||||||
private void createCipher(char[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException {
|
private void initCipher(char[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException {
|
||||||
//Setup the cipher object
|
//Setup the cipher object
|
||||||
cipher = Cipher.getInstance(getTransformationString());
|
cipher = Cipher.getInstance(getTransformationString());
|
||||||
|
|
||||||
//"Convert" the secret key to a AES secret key
|
//"Convert" the secret key to a AES secret key
|
||||||
SecretKey aes = new SecretKeySpec(generatePasswordKey(key).getEncoded(), ENCRYPTION_ALGORITHM);
|
SecretKey aes = new SecretKeySpec(generatePasswordKey(key).getEncoded(), ENCRYPTION_ALGORITHM);
|
||||||
|
|
||||||
|
//Generate the initialization vector
|
||||||
|
IvParameterSpec iv = generateIV(1);
|
||||||
|
|
||||||
//Init the cipher instance
|
//Init the cipher instance
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, aes, generateIV(1));
|
cipher.init(Cipher.ENCRYPT_MODE, aes, iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,8 +126,9 @@ public class CleaverCryptOutputStream extends FilterOutputStream implements ICle
|
||||||
public CleaverCryptOutputStream(OutputStream out, String key) {
|
public CleaverCryptOutputStream(OutputStream out, String key) {
|
||||||
super(out);
|
super(out);
|
||||||
try {
|
try {
|
||||||
createCipher(key.toCharArray());
|
initCipher(key.toCharArray());
|
||||||
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeySpecException | InvalidAlgorithmParameterException | InvalidKeyException e) {
|
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeySpecException | InvalidAlgorithmParameterException | InvalidKeyException e) {
|
||||||
|
//This should never happen...
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,6 +173,10 @@ public class CleaverCryptOutputStream extends FilterOutputStream implements ICle
|
||||||
keyLengthAttr.setValue(Integer.toString(KEY_LENGTH));
|
keyLengthAttr.setValue(Integer.toString(KEY_LENGTH));
|
||||||
element.setAttributeNode(keyLengthAttr);
|
element.setAttributeNode(keyLengthAttr);
|
||||||
|
|
||||||
|
Attr ivAttr = doc.createAttribute("iv");
|
||||||
|
ivAttr.setValue(Byte.toString(cipher.getIV()[0]));
|
||||||
|
element.setAttributeNode(ivAttr);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,12 @@ import java.io.OutputStream;
|
||||||
import java.util.zip.Deflater;
|
import java.util.zip.Deflater;
|
||||||
import java.util.zip.DeflaterOutputStream;
|
import java.util.zip.DeflaterOutputStream;
|
||||||
|
|
||||||
public class CleaverCompressOutputStream extends DeflaterOutputStream implements ICleaverOutputStream {
|
public class CleaverDeflaterOutputStream extends DeflaterOutputStream implements ICleaverOutputStream {
|
||||||
/**
|
/**
|
||||||
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
||||||
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, int, boolean)
|
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, int, boolean)
|
||||||
*/
|
*/
|
||||||
public CleaverCompressOutputStream(OutputStream out, Deflater def, int size, boolean syncFlush) {
|
public CleaverDeflaterOutputStream(OutputStream out, Deflater def, int size, boolean syncFlush) {
|
||||||
super(out, def, size, syncFlush);
|
super(out, def, size, syncFlush);
|
||||||
if(!(out instanceof ICleaverOutputStream)) {
|
if(!(out instanceof ICleaverOutputStream)) {
|
||||||
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
||||||
|
@ -24,7 +24,7 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements
|
||||||
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
||||||
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, int)
|
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, int)
|
||||||
*/
|
*/
|
||||||
public CleaverCompressOutputStream(OutputStream out, Deflater def, int size) {
|
public CleaverDeflaterOutputStream(OutputStream out, Deflater def, int size) {
|
||||||
super(out, def, size);
|
super(out, def, size);
|
||||||
if(!(out instanceof ICleaverOutputStream)) {
|
if(!(out instanceof ICleaverOutputStream)) {
|
||||||
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
||||||
|
@ -35,7 +35,7 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements
|
||||||
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
||||||
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, boolean)
|
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, boolean)
|
||||||
*/
|
*/
|
||||||
public CleaverCompressOutputStream(OutputStream out, Deflater def, boolean syncFlush) {
|
public CleaverDeflaterOutputStream(OutputStream out, Deflater def, boolean syncFlush) {
|
||||||
super(out, def, syncFlush);
|
super(out, def, syncFlush);
|
||||||
if(!(out instanceof ICleaverOutputStream)) {
|
if(!(out instanceof ICleaverOutputStream)) {
|
||||||
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
||||||
|
@ -46,7 +46,7 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements
|
||||||
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
||||||
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater)
|
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater)
|
||||||
*/
|
*/
|
||||||
public CleaverCompressOutputStream(OutputStream out, Deflater def) {
|
public CleaverDeflaterOutputStream(OutputStream out, Deflater def) {
|
||||||
super(out, def);
|
super(out, def);
|
||||||
if(!(out instanceof ICleaverOutputStream)) {
|
if(!(out instanceof ICleaverOutputStream)) {
|
||||||
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
||||||
|
@ -57,7 +57,7 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements
|
||||||
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
||||||
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, boolean)
|
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, boolean)
|
||||||
*/
|
*/
|
||||||
public CleaverCompressOutputStream(OutputStream out, boolean syncFlush) {
|
public CleaverDeflaterOutputStream(OutputStream out, boolean syncFlush) {
|
||||||
super(out, syncFlush);
|
super(out, syncFlush);
|
||||||
if(!(out instanceof ICleaverOutputStream)) {
|
if(!(out instanceof ICleaverOutputStream)) {
|
||||||
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
||||||
|
@ -68,31 +68,20 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements
|
||||||
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
* Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}.
|
||||||
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream)
|
* @see DeflaterOutputStream#DeflaterOutputStream(OutputStream)
|
||||||
*/
|
*/
|
||||||
public CleaverCompressOutputStream(OutputStream out) {
|
public CleaverDeflaterOutputStream(OutputStream out) {
|
||||||
super(out);
|
super(out);
|
||||||
if(!(out instanceof ICleaverOutputStream)) {
|
if(!(out instanceof ICleaverOutputStream)) {
|
||||||
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The name of the used compression algorithm (currently only {@literal Deflate}).
|
|
||||||
*/
|
|
||||||
public String getAlgorithm() {
|
|
||||||
return "Deflate";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Element toElement(Document doc) {
|
public Element toElement(Document doc) {
|
||||||
Element element = doc.createElement("Compress");
|
Element element = doc.createElement("Deflate");
|
||||||
|
|
||||||
Element child = ((ICleaverOutputStream)out).toElement(doc);
|
Element child = ((ICleaverOutputStream)out).toElement(doc);
|
||||||
element.appendChild(child);
|
element.appendChild(child);
|
||||||
|
|
||||||
Attr algorithmAttr = doc.createAttribute("algorithm");
|
|
||||||
algorithmAttr.setValue(getAlgorithm());
|
|
||||||
element.setAttributeNode(algorithmAttr);
|
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package eu.steffo.cleaver.logic.stream.output;
|
||||||
|
|
||||||
|
import org.w3c.dom.Attr;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom {@link OutputStream} that writes the bytes received in input in multiple files with a progressively increasing number (.c1, .c2, .c3, and so on).
|
||||||
|
*
|
||||||
|
* Bytes are written one at a time to the files in a round-robin format until the stream is exausted.
|
||||||
|
*/
|
||||||
|
public class CleaverForkFileOutputStream extends OutputStream implements ICleaverOutputStream {
|
||||||
|
private final String fileBaseName;
|
||||||
|
private FileOutputStream[] fileOutputStreams;
|
||||||
|
private int writeTo;
|
||||||
|
private long partSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a CleaverForkFileOutputStream.
|
||||||
|
* @param fileBaseName The name of the files without the extension. If it is {@literal example}, the created files will be {@literal example.c1}, {@literal example.c2}, and so on.
|
||||||
|
* @param parts The number of parts to be created.
|
||||||
|
*/
|
||||||
|
public CleaverForkFileOutputStream(String fileBaseName, int parts) throws FileNotFoundException {
|
||||||
|
this.fileBaseName = fileBaseName;
|
||||||
|
this.fileOutputStreams = new FileOutputStream[parts];
|
||||||
|
for(int i = 0; i < parts; i++) {
|
||||||
|
File file = new File(String.format("%s.c%s", fileBaseName, i));
|
||||||
|
this.fileOutputStreams[i] = new FileOutputStream(file);
|
||||||
|
}
|
||||||
|
this.writeTo = 0;
|
||||||
|
this.partSize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element toElement(Document doc) {
|
||||||
|
Element element = doc.createElement("Fork");
|
||||||
|
element.setTextContent(fileBaseName);
|
||||||
|
|
||||||
|
Attr partSizeAttr = doc.createAttribute("part-size");
|
||||||
|
partSizeAttr.setValue(Long.toString(partSize));
|
||||||
|
element.setAttributeNode(partSizeAttr);
|
||||||
|
|
||||||
|
Attr partCountAttr = doc.createAttribute("parts");
|
||||||
|
partCountAttr.setValue(Long.toString(fileOutputStreams.length));
|
||||||
|
element.setAttributeNode(partCountAttr);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
fileOutputStreams[writeTo].write(b);
|
||||||
|
writeTo += 1;
|
||||||
|
if(writeTo >= fileOutputStreams.length) {
|
||||||
|
writeTo = 0;
|
||||||
|
partSize += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The name of the files without the extension. If it is {@literal example}, the created files will be {@literal example.c1}, {@literal example.c2}, and so on.
|
||||||
|
*/
|
||||||
|
public String getFileBaseName() {
|
||||||
|
return fileBaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current maximum size of a part, in bytes.
|
||||||
|
*/
|
||||||
|
public long getPartSize() {
|
||||||
|
return partSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of file parts to create.
|
||||||
|
*/
|
||||||
|
public int getParts() {
|
||||||
|
return fileOutputStreams.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of the next file where a byte should be written, from 0 to the number of parts -1.
|
||||||
|
*/
|
||||||
|
public int getWriteTo() {
|
||||||
|
return writeTo;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package eu.steffo.cleaver.logic.stream.output;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
|
public class CleaverSimpleFileOutputStream extends FileOutputStream implements ICleaverOutputStream {
|
||||||
|
private final String fileBaseName;
|
||||||
|
|
||||||
|
public CleaverSimpleFileOutputStream(String fileBaseName) throws FileNotFoundException {
|
||||||
|
super(String.format("%s.c0", fileBaseName));
|
||||||
|
this.fileBaseName = fileBaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element toElement(Document doc) {
|
||||||
|
Element element = doc.createElement("Simple");
|
||||||
|
element.setTextContent(fileBaseName);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,6 @@ public class CleaverSplitFileOutputStream extends OutputStream implements ICleav
|
||||||
private final String fileBaseName;
|
private final String fileBaseName;
|
||||||
private long currentByteCount;
|
private long currentByteCount;
|
||||||
private long maximumByteCount;
|
private long maximumByteCount;
|
||||||
private long totalByteCount;
|
|
||||||
private int currentFileCount;
|
private int currentFileCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +59,6 @@ public class CleaverSplitFileOutputStream extends OutputStream implements ICleav
|
||||||
}
|
}
|
||||||
currentFileOutputStream.write(b);
|
currentFileOutputStream.write(b);
|
||||||
currentByteCount += 1;
|
currentByteCount += 1;
|
||||||
totalByteCount += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -96,13 +94,6 @@ public class CleaverSplitFileOutputStream extends OutputStream implements ICleav
|
||||||
return currentFileCount;
|
return currentFileCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The number of bytes that have already been written.
|
|
||||||
*/
|
|
||||||
public long getTotalByteCount() {
|
|
||||||
return totalByteCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Element toElement(Document doc) {
|
public Element toElement(Document doc) {
|
||||||
Element element = doc.createElement("Split");
|
Element element = doc.createElement("Split");
|
||||||
|
@ -116,10 +107,6 @@ public class CleaverSplitFileOutputStream extends OutputStream implements ICleav
|
||||||
partCountAttr.setValue(Long.toString(currentFileCount));
|
partCountAttr.setValue(Long.toString(currentFileCount));
|
||||||
element.setAttributeNode(partCountAttr);
|
element.setAttributeNode(partCountAttr);
|
||||||
|
|
||||||
Attr totalSizeAttr = doc.createAttribute("total-size");
|
|
||||||
totalSizeAttr.setValue(Long.toString(totalByteCount));
|
|
||||||
element.setAttributeNode(totalSizeAttr);
|
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,5 +11,5 @@ public interface ICleaverOutputStream extends ICleaverStream {
|
||||||
* @param doc The {@link Document} the {@link Element} should be created in.
|
* @param doc The {@link Document} the {@link Element} should be created in.
|
||||||
* @return The created {@link Element}.
|
* @return The created {@link Element}.
|
||||||
*/
|
*/
|
||||||
public Element toElement(Document doc);
|
Element toElement(Document doc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,10 @@ open module eu.steffo.cleaver {
|
||||||
exports eu.steffo.cleaver.gui.panels;
|
exports eu.steffo.cleaver.gui.panels;
|
||||||
exports eu.steffo.cleaver.gui.panels.rows;
|
exports eu.steffo.cleaver.gui.panels.rows;
|
||||||
exports eu.steffo.cleaver.gui.panels.rows.option;
|
exports eu.steffo.cleaver.gui.panels.rows.option;
|
||||||
exports eu.steffo.cleaver.logic;
|
|
||||||
exports eu.steffo.cleaver.logic.compress;
|
|
||||||
exports eu.steffo.cleaver.logic.crypt;
|
|
||||||
exports eu.steffo.cleaver.logic.progress;
|
exports eu.steffo.cleaver.logic.progress;
|
||||||
exports eu.steffo.cleaver.logic.split;
|
exports eu.steffo.cleaver.logic.config;
|
||||||
|
exports eu.steffo.cleaver.logic.job;
|
||||||
|
exports eu.steffo.cleaver.logic.stream;
|
||||||
|
exports eu.steffo.cleaver.logic.stream.input;
|
||||||
|
exports eu.steffo.cleaver.logic.stream.output;
|
||||||
}
|
}
|
Loading…
Reference in a new issue