Revize 03a2d08f
Přidáno uživatelem Michal Horký před téměř 5 roky(ů)
demo_mh/Deserializer/src/deserialize/Deserializer.java | ||
---|---|---|
35 | 35 |
@Override |
36 | 36 |
public void init() throws Exception { |
37 | 37 |
super.init(); |
38 |
testing = false;
|
|
38 |
testing = true;
|
|
39 | 39 |
} |
40 | 40 |
|
41 | 41 |
@Override |
demo_mh/Deserializer/src/deserialize/Formatter.java | ||
---|---|---|
1 |
package deserialize; |
|
2 |
|
|
3 |
public class Formatter { |
|
4 |
|
|
5 |
public static int createInt(byte first, byte second) { |
|
6 |
return ((first & 0xFF) << 8) | (second & 0xFF); |
|
7 |
} |
|
8 |
|
|
9 |
} |
project/.gitignore | ||
---|---|---|
1 |
/.metadata/ |
project/Deserializer/.classpath | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<classpath> |
|
3 |
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> |
|
4 |
<classpathentry kind="src" path="src"/> |
|
5 |
<classpathentry kind="lib" path="D:/Michal/University/1/LS/ASWI/semestralky/Deserializer/aswi2020horky/project/Deserializer/libs/jackson-core-asl-1.9.13.jar"/> |
|
6 |
<classpathentry kind="lib" path="D:/Michal/University/1/LS/ASWI/semestralky/Deserializer/aswi2020horky/project/Deserializer/libs/jackson-mapper-asl-1.9.13.jar"/> |
|
7 |
<classpathentry kind="output" path="bin"/> |
|
8 |
</classpath> |
project/Deserializer/.gitignore | ||
---|---|---|
1 |
/bin/ |
project/Deserializer/.project | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<projectDescription> |
|
3 |
<name>Deserializer</name> |
|
4 |
<comment></comment> |
|
5 |
<projects> |
|
6 |
</projects> |
|
7 |
<buildSpec> |
|
8 |
<buildCommand> |
|
9 |
<name>org.eclipse.jdt.core.javabuilder</name> |
|
10 |
<arguments> |
|
11 |
</arguments> |
|
12 |
</buildCommand> |
|
13 |
</buildSpec> |
|
14 |
<natures> |
|
15 |
<nature>org.eclipse.jdt.core.javanature</nature> |
|
16 |
</natures> |
|
17 |
</projectDescription> |
project/Deserializer/libs/Licenses | ||
---|---|---|
1 |
|
|
2 |
JACKSON JSON |
|
3 |
|
|
4 |
This copy of Jackson JSON processor streaming parser/generator is licensed under the |
|
5 |
Apache (Software) License, version 2.0 ("the License"). |
|
6 |
See the License for details about distribution rights, and the |
|
7 |
specific rights regarding derivate works. |
|
8 |
|
|
9 |
You may obtain a copy of the License at: |
|
10 |
|
|
11 |
http://www.apache.org/licenses/LICENSE-2.0 |
|
12 |
|
|
13 |
************************************************************ |
|
14 |
|
|
15 |
JDESERIALIZE |
|
16 |
|
|
17 |
https://code.google.com/archive/p/jdeserialize/ |
|
18 |
https://opensource.org/licenses/BSD-3-Clause |
|
19 |
Copyright <YEAR> <COPYRIGHT HOLDER> |
|
20 |
|
|
21 |
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
22 |
|
|
23 |
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
24 |
|
|
25 |
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
26 |
|
|
27 |
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
|
28 |
|
|
29 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
project/Deserializer/results.json | ||
---|---|---|
1 |
{ |
|
2 |
"handle" : 8257537, |
|
3 |
"isExceptionObject" : false, |
|
4 |
"type" : "INSTANCE", |
|
5 |
"fielddata" : { |
|
6 |
"[cd 0x7e0000: name java.util.Hashtable uid 1421746759512286392]" : { |
|
7 |
"jdeserialize.field@204b315d" : 0.75, |
|
8 |
"jdeserialize.field@2e8ccb24" : 8 |
|
9 |
} |
|
10 |
}, |
|
11 |
"classdesc" : { |
|
12 |
"handle" : 8257536, |
|
13 |
"isExceptionObject" : false, |
|
14 |
"type" : "CLASSDESC", |
|
15 |
"classtype" : "NORMALCLASS", |
|
16 |
"name" : "java.util.Hashtable", |
|
17 |
"serialVersionUID" : 1421746759512286392, |
|
18 |
"descflags" : 3, |
|
19 |
"fields" : [ { |
|
20 |
"type" : "FLOAT", |
|
21 |
"name" : "loadFactor", |
|
22 |
"classname" : null, |
|
23 |
"javaType" : "float", |
|
24 |
"innerClassReference" : false |
|
25 |
}, { |
|
26 |
"type" : "INTEGER", |
|
27 |
"name" : "threshold", |
|
28 |
"classname" : null, |
|
29 |
"javaType" : "int", |
|
30 |
"innerClassReference" : false |
|
31 |
} ], |
|
32 |
"innerclasses" : [ ], |
|
33 |
"annotations" : [ ], |
|
34 |
"superclass" : null, |
|
35 |
"interfaces" : null, |
|
36 |
"enumconstants" : [ ], |
|
37 |
"arrayClass" : false, |
|
38 |
"innerClass" : false, |
|
39 |
"staticMemberClass" : false, |
|
40 |
"localInnerClass" : false, |
|
41 |
"exceptionObject" : false |
|
42 |
}, |
|
43 |
"annotations" : { |
|
44 |
"[cd 0x7e0000: name java.util.Hashtable uid 1421746759512286392]" : [ { |
|
45 |
"handle" : 0, |
|
46 |
"isExceptionObject" : false, |
|
47 |
"type" : "BLOCKDATA", |
|
48 |
"buf" : "AAAACwAAAAA=", |
|
49 |
"exceptionObject" : false |
|
50 |
} ] |
|
51 |
}, |
|
52 |
"exceptionObject" : false |
|
53 |
} |
project/Deserializer/src/Converter.java | ||
---|---|---|
1 |
import java.io.File; |
|
2 |
import java.io.IOException; |
|
3 |
import java.util.List; |
|
4 |
|
|
5 |
import org.codehaus.jackson.map.ObjectMapper; |
|
6 |
import org.codehaus.jackson.map.ObjectWriter; |
|
7 |
|
|
8 |
import jdeserialize.content; |
|
9 |
import jdeserialize.jdeserialize; |
|
10 |
|
|
11 |
public class Converter extends Thread { |
|
12 |
|
|
13 |
private Deserializer main; |
|
14 |
|
|
15 |
private File input; |
|
16 |
private File output; |
|
17 |
|
|
18 |
public Converter(Deserializer main, File inputFilename, File outputFilename) { |
|
19 |
this.main = main; |
|
20 |
this.input = inputFilename; |
|
21 |
this.output = outputFilename; |
|
22 |
} |
|
23 |
|
|
24 |
@Override |
|
25 |
public void run() { |
|
26 |
super.run(); |
|
27 |
|
|
28 |
try { |
|
29 |
String json = convert(FileWorker.loadByteArray(input)); |
|
30 |
|
|
31 |
String title = "Ulo?en? JSON"; |
|
32 |
if (FileWorker.saveJson(output, json)) { |
|
33 |
System.out.println("The JSON file was saved correctly."); |
|
34 |
Report.info(title, null, "Ulo?en? JSON souboru prob?hlo v po??dku."); |
|
35 |
} else { |
|
36 |
System.out.println("There was an error saving the JSON file."); |
|
37 |
Report.error(title, null, "P?i ukl?d?n? JSON souboru nastala chyba."); |
|
38 |
} |
|
39 |
} catch (IOException e) { |
|
40 |
System.out.println("There was an error loading the file."); |
|
41 |
e.printStackTrace(); |
|
42 |
Report.error("Na??t?n? souboru", null, "P?i na??t?n? souboru do?lo k chyb?."); |
|
43 |
} |
|
44 |
|
|
45 |
main.convertIsComplete(); |
|
46 |
} |
|
47 |
|
|
48 |
private String convert(byte[] buffer) { |
|
49 |
try { |
|
50 |
System.out.println("Deserialization begins."); |
|
51 |
jdeserialize deserializer = new jdeserialize(buffer); |
|
52 |
|
|
53 |
// gets the "contents" into an array - returnes the deserialization of all |
|
54 |
// 'writes' into serialized object via objectOutputStream |
|
55 |
List<content> cntnts = deserializer.getContent(); |
|
56 |
|
|
57 |
// testing with only first of the contents |
|
58 |
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); |
|
59 |
String json = ow.writeValueAsString(cntnts.get(0)); |
|
60 |
|
|
61 |
System.out.println("Task completed."); |
|
62 |
return json; |
|
63 |
} catch (IOException e) { |
|
64 |
System.out.println("An error occurred while processing!"); |
|
65 |
e.printStackTrace(); |
|
66 |
return null; |
|
67 |
} |
|
68 |
} |
|
69 |
|
|
70 |
} |
project/Deserializer/src/Deserializer.java | ||
---|---|---|
1 |
import java.io.File; |
|
2 |
|
|
3 |
import javafx.application.Application; |
|
4 |
import javafx.geometry.Insets; |
|
5 |
import javafx.geometry.Pos; |
|
6 |
import javafx.scene.Parent; |
|
7 |
import javafx.scene.Scene; |
|
8 |
import javafx.scene.control.Button; |
|
9 |
import javafx.scene.control.Label; |
|
10 |
import javafx.scene.layout.HBox; |
|
11 |
import javafx.scene.layout.VBox; |
|
12 |
import javafx.stage.FileChooser; |
|
13 |
import javafx.stage.Stage; |
|
14 |
|
|
15 |
public class Deserializer extends Application { |
|
16 |
|
|
17 |
private Stage stage; |
|
18 |
private File inputFile; |
|
19 |
private File outputFile; |
|
20 |
|
|
21 |
Button convert; |
|
22 |
|
|
23 |
// TODO delete after deserializer debugging is complete... |
|
24 |
private boolean testing; |
|
25 |
|
|
26 |
public static void main(String[] args) { |
|
27 |
launch(args); |
|
28 |
} |
|
29 |
|
|
30 |
@Override |
|
31 |
public void init() throws Exception { |
|
32 |
super.init(); |
|
33 |
testing = true; |
|
34 |
} |
|
35 |
|
|
36 |
@Override |
|
37 |
public void start(Stage stage) throws Exception { |
|
38 |
this.stage = stage; |
|
39 |
stage.setTitle("Java object universal deserializer"); |
|
40 |
stage.setScene(createScene()); |
|
41 |
stage.setMinWidth(400); |
|
42 |
stage.show(); |
|
43 |
} |
|
44 |
|
|
45 |
private Scene createScene() { |
|
46 |
return new Scene(createLayout()); |
|
47 |
} |
|
48 |
|
|
49 |
private Parent createLayout() { |
|
50 |
VBox layout = new VBox(); |
|
51 |
layout.setPadding(new Insets(10.0)); |
|
52 |
layout.setSpacing(10.0); |
|
53 |
|
|
54 |
Label forInputFile = new Label("Soubor k deserializaci:"); |
|
55 |
Label inputFile = new Label(" Je?t? nebyl vybr?n ??dn? soubor..."); |
|
56 |
inputFile.setStyle("-fx-font-style: italic;"); |
|
57 |
VBox forInput = new VBox(); |
|
58 |
forInput.getChildren().add(forInputFile); |
|
59 |
forInput.getChildren().add(inputFile); |
|
60 |
|
|
61 |
Label forOutputFile = new Label("V?stupn? soubor:"); |
|
62 |
Label outputFile = new Label(" Je?t? nebyl vybr?n ??dn? soubor..."); |
|
63 |
outputFile.setStyle("-fx-font-style: italic;"); |
|
64 |
VBox forOutput = new VBox(); |
|
65 |
forOutput.getChildren().add(forOutputFile); |
|
66 |
forOutput.getChildren().add(outputFile); |
|
67 |
|
|
68 |
convert = new Button("P?ev?st"); |
|
69 |
convert.setOnAction(event -> { |
|
70 |
// a.data a b.data are customers test files (binary files). |
|
71 |
convert.setDisable(true); |
|
72 |
Converter thread = new Converter(this, testing ? new File("a.data") : this.inputFile, testing ? new File("results.json") : this.outputFile); |
|
73 |
thread.start(); |
|
74 |
}); |
|
75 |
convert.setDisable(!testing); |
|
76 |
Button setInputFile = new Button("Vstupn? soubor"); |
|
77 |
setInputFile.setOnAction(event -> { |
|
78 |
FileChooser fCh = new FileChooser(); |
|
79 |
fCh.setInitialDirectory(new File(".")); |
|
80 |
// The input can be a zip file or file without a specific extension -> file chooser without extension filters... |
|
81 |
// fCh.getExtensionFilters().add(new FileChooser.ExtensionFilter("Binary Files", "*.out")); |
|
82 |
File file = fCh.showOpenDialog(stage); |
|
83 |
if (file != null) { |
|
84 |
this.inputFile = file; |
|
85 |
inputFile.setText(this.inputFile == null ? "" : this.inputFile.getAbsolutePath()); |
|
86 |
inputFile.setStyle("-fx-font-weight: bold;"); |
|
87 |
convert.setDisable(this.inputFile == null || this.outputFile == null); |
|
88 |
} |
|
89 |
}); |
|
90 |
Button setOutputFile = new Button("V?stupn? soubor"); |
|
91 |
setOutputFile.setOnAction(event -> { |
|
92 |
FileChooser fCh = new FileChooser(); |
|
93 |
fCh.setInitialDirectory(new File(".")); |
|
94 |
fCh.getExtensionFilters().add(new FileChooser.ExtensionFilter("JSON Files", "*.json")); |
|
95 |
File file = fCh.showSaveDialog(stage); |
|
96 |
if (file != null) { |
|
97 |
this.outputFile = file; |
|
98 |
outputFile.setText(this.outputFile == null ? "" : this.outputFile.getAbsolutePath()); |
|
99 |
outputFile.setStyle("-fx-font-weight: bold;"); |
|
100 |
convert.setDisable(this.inputFile == null || this.outputFile == null); |
|
101 |
} |
|
102 |
}); |
|
103 |
HBox footer = new HBox(); |
|
104 |
footer.setSpacing(10.0); |
|
105 |
footer.setAlignment(Pos.CENTER_RIGHT); |
|
106 |
footer.getChildren().add(setInputFile); |
|
107 |
footer.getChildren().add(setOutputFile); |
|
108 |
footer.getChildren().add(convert); |
|
109 |
|
|
110 |
layout.getChildren().add(forInput); |
|
111 |
layout.getChildren().add(forOutput); |
|
112 |
layout.getChildren().add(footer); |
|
113 |
|
|
114 |
return layout; |
|
115 |
} |
|
116 |
|
|
117 |
public void convertIsComplete() { |
|
118 |
convert.setDisable(false); |
|
119 |
} |
|
120 |
|
|
121 |
} |
project/Deserializer/src/FileWorker.java | ||
---|---|---|
1 |
import java.io.BufferedInputStream; |
|
2 |
import java.io.BufferedWriter; |
|
3 |
import java.io.File; |
|
4 |
import java.io.FileInputStream; |
|
5 |
import java.io.FileWriter; |
|
6 |
import java.io.IOException; |
|
7 |
import java.util.ArrayList; |
|
8 |
import java.util.List; |
|
9 |
import java.util.NoSuchElementException; |
|
10 |
import java.util.zip.ZipException; |
|
11 |
import java.util.zip.ZipInputStream; |
|
12 |
|
|
13 |
public class FileWorker { |
|
14 |
|
|
15 |
public static byte[] loadByteArray(File file) throws IOException { |
|
16 |
byte buffer[]; |
|
17 |
|
|
18 |
/* |
|
19 |
* Note. |
|
20 |
* For ZIP - the first four bytes should be one of the following combinations: |
|
21 |
* 50 4B 03 04 |
|
22 |
* 50 4B 05 06 (empty archive) |
|
23 |
* 50 4B 07 08 (spanned archive) |
|
24 |
* Source: https://en.wikipedia.org/wiki/List_of_file_signatures |
|
25 |
*/ |
|
26 |
try { |
|
27 |
|
|
28 |
ZipInputStream zipIS = new ZipInputStream(new FileInputStream(file)); |
|
29 |
|
|
30 |
if (zipIS.getNextEntry() == null) { |
|
31 |
zipIS.close(); |
|
32 |
throw new NoSuchElementException(); |
|
33 |
} |
|
34 |
|
|
35 |
System.out.println("The file is a zip archive..."); |
|
36 |
List<Byte> _buffer = new ArrayList<Byte>(); |
|
37 |
while (true) { |
|
38 |
int value = zipIS.read(); |
|
39 |
if (value < 0) { |
|
40 |
break; |
|
41 |
} else { |
|
42 |
_buffer.add((byte) value); |
|
43 |
} |
|
44 |
} |
|
45 |
|
|
46 |
buffer = new byte[_buffer.size()]; |
|
47 |
for (int i = 0; i < buffer.length; i++) { |
|
48 |
buffer[i] = _buffer.get(i); |
|
49 |
} |
|
50 |
|
|
51 |
zipIS.close(); |
|
52 |
|
|
53 |
} catch (NoSuchElementException | ZipException e) { |
|
54 |
|
|
55 |
System.out.println("The file is not a zip archive..."); |
|
56 |
buffer = new byte[(int) file.length()]; |
|
57 |
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); |
|
58 |
bis.read(buffer); |
|
59 |
bis.close(); |
|
60 |
|
|
61 |
} |
|
62 |
|
|
63 |
System.out.println("Bytes from the file were loaded correctly."); |
|
64 |
return buffer; |
|
65 |
} |
|
66 |
|
|
67 |
public static boolean saveJson(File file, String json) { |
|
68 |
boolean retValue = false; |
|
69 |
try { |
|
70 |
FileWriter fw = new FileWriter(file); |
|
71 |
BufferedWriter bw = new BufferedWriter(fw); |
|
72 |
bw.write(json); |
|
73 |
bw.flush(); |
|
74 |
bw.close(); |
|
75 |
retValue = true; |
|
76 |
} catch (IOException e) { |
|
77 |
e.printStackTrace(); |
|
78 |
} |
|
79 |
return retValue; |
|
80 |
} |
|
81 |
|
|
82 |
} |
project/Deserializer/src/Report.java | ||
---|---|---|
1 |
import com.sun.javafx.stage.StageHelper; |
|
2 |
|
|
3 |
import javafx.application.Platform; |
|
4 |
import javafx.geometry.Rectangle2D; |
|
5 |
import javafx.scene.control.Alert; |
|
6 |
import javafx.scene.control.Alert.AlertType; |
|
7 |
import javafx.stage.Screen; |
|
8 |
|
|
9 |
public class Report { |
|
10 |
|
|
11 |
private static final int HEIGHT = 200; |
|
12 |
private static final int WIDTH = 500; |
|
13 |
|
|
14 |
private static void setPosition(Alert alert) { |
|
15 |
if (StageHelper.getStages() != null && StageHelper.getStages().size() != 0) { |
|
16 |
if (Screen.getPrimary() != null && Screen.getPrimary().getVisualBounds() != null) { |
|
17 |
Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds(); |
|
18 |
alert.setX((primScreenBounds.getWidth() - WIDTH - 20) / 2); |
|
19 |
alert.setY((primScreenBounds.getHeight() - HEIGHT - 20) / 3); |
|
20 |
} |
|
21 |
alert.initOwner(StageHelper.getStages().get(StageHelper.getStages().size() - 1)); |
|
22 |
} |
|
23 |
} |
|
24 |
|
|
25 |
private static Alert createAlert(AlertType type, String title, String header, String content) { |
|
26 |
Alert alert = new Alert(type); |
|
27 |
alert.setResizable(true); |
|
28 |
alert.getDialogPane().setPrefWidth(WIDTH); |
|
29 |
alert.setTitle(title); |
|
30 |
alert.setHeaderText(header); |
|
31 |
alert.setContentText(content); |
|
32 |
setPosition(alert); |
|
33 |
return alert; |
|
34 |
} |
|
35 |
|
|
36 |
public static void error(String title, String header, String content) { |
|
37 |
Platform.runLater(()->{ |
|
38 |
createAlert(AlertType.WARNING, title, header, content).showAndWait(); |
|
39 |
}); |
|
40 |
} |
|
41 |
|
|
42 |
public static void info(String title, String header, String content) { |
|
43 |
Platform.runLater(()->{ |
|
44 |
createAlert(AlertType.INFORMATION, title, header, content).showAndWait(); |
|
45 |
}); |
|
46 |
} |
|
47 |
|
|
48 |
public static boolean confirm(String title, String header, String content) { |
|
49 |
Alert alert = createAlert(AlertType.CONFIRMATION, title, header, content); |
|
50 |
alert.showAndWait(); |
|
51 |
if (alert.getResult().getText().equals("OK")) { |
|
52 |
return true; |
|
53 |
} else { |
|
54 |
return false; |
|
55 |
} |
|
56 |
} |
|
57 |
|
|
58 |
} |
project/Deserializer/src/jdeserialize/ExceptionReadException.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
|
|
4 |
/** |
|
5 |
* Exception used to signal that an exception object was successfully read from the |
|
6 |
* stream. This object holds a reference to the serialized exception object. |
|
7 |
*/ |
|
8 |
public class ExceptionReadException extends IOException { |
|
9 |
public static final long serialVersionUID = 2277356908919221L; |
|
10 |
public content exceptionobj; |
|
11 |
/** |
|
12 |
* Constructor. |
|
13 |
* @param c the serialized exception object that was read |
|
14 |
*/ |
|
15 |
public ExceptionReadException(content c) { |
|
16 |
super("serialized exception read during stream"); |
|
17 |
this.exceptionobj = c; |
|
18 |
} |
|
19 |
/** |
|
20 |
* Gets the Exception object that was thrown. |
|
21 |
* @return the content representing the serialized exception object |
|
22 |
*/ |
|
23 |
public content getExceptionObject() { |
|
24 |
return exceptionobj; |
|
25 |
} |
|
26 |
} |
|
27 |
|
project/Deserializer/src/jdeserialize/Getopt.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.util.*; |
|
3 |
|
|
4 |
/** |
|
5 |
* Simple getopt()-like implementation. |
|
6 |
*/ |
|
7 |
public class Getopt { |
|
8 |
private Map<String, Integer> options; |
|
9 |
private List<String> otherargs; |
|
10 |
private Map<String, String> descriptions; |
|
11 |
private Map<String, List<String>> optvals; |
|
12 |
|
|
13 |
public class OptionParseException extends Exception { |
|
14 |
public static final long serialVersionUID = 2898924890585885551L; |
|
15 |
public OptionParseException(String message) { |
|
16 |
super(message); |
|
17 |
} |
|
18 |
} |
|
19 |
|
|
20 |
/** |
|
21 |
* Gets the list arguments specified that were *not* options or their arguments, in |
|
22 |
* the order they were specified. |
|
23 |
* |
|
24 |
* @return the list of non-option String arguments |
|
25 |
*/ |
|
26 |
public List<String> getOtherArguments() { |
|
27 |
return otherargs; |
|
28 |
} |
|
29 |
|
|
30 |
/** |
|
31 |
* Gets the set of all options specified, as well as the list of their arguments. |
|
32 |
* |
|
33 |
* @return a map of all options specified; values are lists of arguments |
|
34 |
*/ |
|
35 |
public Map<String, List<String>> getOptionValues() { |
|
36 |
return optvals; |
|
37 |
} |
|
38 |
|
|
39 |
/** |
|
40 |
* Constructor. |
|
41 |
* |
|
42 |
* @param options Map of options to parse. The key should be an option string (including |
|
43 |
* any initial dashes), and the value should be an Integer representing the number of |
|
44 |
* arguments to parse following the option. |
|
45 |
* @param descriptions Map of option descriptions. |
|
46 |
*/ |
|
47 |
public Getopt(Map<String, Integer> options, Map<String, String> descriptions) { |
|
48 |
this.options = options; |
|
49 |
this.descriptions = descriptions; |
|
50 |
} |
|
51 |
/** |
|
52 |
* Constructor. |
|
53 |
*/ |
|
54 |
public Getopt() { |
|
55 |
this.options = new HashMap<String, Integer>(); |
|
56 |
this.descriptions = new HashMap<String, String>(); |
|
57 |
} |
|
58 |
|
|
59 |
/** |
|
60 |
* Determines whether or not the option was specified when the arguments were parsed. |
|
61 |
* |
|
62 |
* @return true iff the argument was specified (with the correct number of arguments). |
|
63 |
*/ |
|
64 |
public boolean hasOption(String opt) { |
|
65 |
return optvals.containsKey(opt); |
|
66 |
} |
|
67 |
|
|
68 |
/** |
|
69 |
* Gets the list of arguments for a given option, or null if the option wasn't |
|
70 |
* specified. |
|
71 |
* |
|
72 |
* @param option the option |
|
73 |
* @return the list of arguments for option |
|
74 |
*/ |
|
75 |
public List<String> getArguments(String option) { |
|
76 |
return optvals.get(option); |
|
77 |
} |
|
78 |
|
|
79 |
/** |
|
80 |
* Add an option to the internal set, including the number of arguments and the |
|
81 |
* description. |
|
82 |
* |
|
83 |
* @param option option string, including any leading dashes |
|
84 |
* @param arguments number of arguments |
|
85 |
* @param description description of the option |
|
86 |
*/ |
|
87 |
public void addOption(String option, int arguments, String description) { |
|
88 |
options.put(option, arguments); |
|
89 |
descriptions.put(option, description); |
|
90 |
} |
|
91 |
|
|
92 |
/** |
|
93 |
* Do the parsing/validation. |
|
94 |
* @param args arguments to parse |
|
95 |
* @throws OptionParseException if a parse error occurs (the exception message will |
|
96 |
* have details) |
|
97 |
*/ |
|
98 |
public void parse(String[] args) throws OptionParseException { |
|
99 |
this.otherargs = new ArrayList<String>(); |
|
100 |
this.optvals = new HashMap<String, List<String>>(); |
|
101 |
|
|
102 |
for(int i = 0; i < args.length; i++) { |
|
103 |
if(optvals != null) { |
|
104 |
Integer count = options.get(args[i]); |
|
105 |
if(count != null) { |
|
106 |
ArrayList<String> al = new ArrayList<String>(count.intValue()); |
|
107 |
for(int j = 0; j < count; j++) { |
|
108 |
if(i+1+j >= args.length) { |
|
109 |
throw new OptionParseException("expected " + count + " arguments after " + args[i]); |
|
110 |
} |
|
111 |
al.add(args[i+1+j]); |
|
112 |
} |
|
113 |
List<String> oldal = optvals.get(args[i]); |
|
114 |
if(oldal == null) { |
|
115 |
optvals.put(args[i], al); |
|
116 |
} else { |
|
117 |
oldal.addAll(al); |
|
118 |
} |
|
119 |
i += count; |
|
120 |
continue; |
|
121 |
} |
|
122 |
} |
|
123 |
otherargs.add(args[i]); |
|
124 |
} |
|
125 |
} |
|
126 |
|
|
127 |
/** |
|
128 |
* Get a tabular description of all options and their descriptions, one per line. |
|
129 |
*/ |
|
130 |
public String getDescriptionString() { |
|
131 |
String linesep = System.getProperty("line.separator"); |
|
132 |
StringBuffer sb = new StringBuffer(); |
|
133 |
if(options != null && options.size() > 0) { |
|
134 |
sb.append("Options:").append(linesep); |
|
135 |
TreeSet<String> opts = new TreeSet<String>(this.options.keySet()); |
|
136 |
for(String opt: opts) { |
|
137 |
sb.append(" ").append(opt); |
|
138 |
for(int i = 0; i < options.get(opt); i++) { |
|
139 |
sb.append(" arg").append(i+1); |
|
140 |
} |
|
141 |
sb.append(": ").append(descriptions.get(opt)).append(linesep); |
|
142 |
} |
|
143 |
} |
|
144 |
return sb.toString(); |
|
145 |
} |
|
146 |
|
|
147 |
public static void main(String[] args) { |
|
148 |
try { |
|
149 |
Getopt go = new Getopt(); |
|
150 |
go.addOption("-optzero", 0, "zero-arg constructor"); |
|
151 |
go.addOption("-optone", 1, "one-arg constructor"); |
|
152 |
go.addOption("-opttwo", 2, "two-arg constructor"); |
|
153 |
go.parse(args); |
|
154 |
System.out.println(go.getDescriptionString()); |
|
155 |
System.out.println("options:"); |
|
156 |
Map<String, List<String>> optvals = go.getOptionValues(); |
|
157 |
for(String opt: optvals.keySet()) { |
|
158 |
System.out.print(" " + opt); |
|
159 |
for(String optval: optvals.get(opt)) { |
|
160 |
System.out.print(" " + optval); |
|
161 |
} |
|
162 |
System.out.println(""); |
|
163 |
} |
|
164 |
System.out.println(""); |
|
165 |
System.out.println("otherargs:"); |
|
166 |
for(String arg: go.getOtherArguments()) { |
|
167 |
System.out.println(" " + arg); |
|
168 |
} |
|
169 |
} catch (Throwable t) { |
|
170 |
t.printStackTrace(); |
|
171 |
} |
|
172 |
} |
|
173 |
} |
project/Deserializer/src/jdeserialize/LoggerInputStream.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
import java.io.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p> |
|
7 |
* An InputStream designed to record data passing through the stream after a call to |
|
8 |
* record() is made. After record() is called, the results from every read will |
|
9 |
* be stored in an * internal buffer. The contents of the buffer can be |
|
10 |
* retrieved by getRecordedData(); to stop recording and clear the internal |
|
11 |
* buffer, call stopRecording(). |
|
12 |
* </p> |
|
13 |
* |
|
14 |
* <p> |
|
15 |
* <b>Note</b>: calls to mark() and reset() are merely passed through to the inner stream; if |
|
16 |
* recording is active, the buffer won't be backtracked by reset(). |
|
17 |
* </p> |
|
18 |
*/ |
|
19 |
public class LoggerInputStream extends InputStream { |
|
20 |
private ByteArrayInputStream innerStream = null; |
|
21 |
private ByteArrayOutputStream baos = null; |
|
22 |
private boolean recording = false; |
|
23 |
|
|
24 |
public LoggerInputStream(byte[] buffer) { |
|
25 |
super(); |
|
26 |
this.innerStream = new ByteArrayInputStream(buffer); |
|
27 |
} |
|
28 |
public synchronized int read() throws IOException { |
|
29 |
int i = innerStream.read(); |
|
30 |
if(recording && i != -1) { |
|
31 |
if(i > 255 || i < 0) { |
|
32 |
throw new IOException("non-byte, non--1 value read from inner stream: " + i); |
|
33 |
} |
|
34 |
baos.write((byte)i); |
|
35 |
} |
|
36 |
return i; |
|
37 |
} |
|
38 |
public synchronized int read(byte[] b) throws IOException { |
|
39 |
return this.read(b, 0, b.length); |
|
40 |
} |
|
41 |
public synchronized int read(byte[] b, int off, int len) throws IOException { |
|
42 |
int retval = innerStream.read(b, off, len); |
|
43 |
if(recording && retval > 0) { |
|
44 |
if(retval > len) { |
|
45 |
throw new IOException("inner stream read(byte[], int, int) violating contract; return value > len: " + retval); |
|
46 |
} |
|
47 |
baos.write(b, off, retval); |
|
48 |
} |
|
49 |
return retval; |
|
50 |
} |
|
51 |
public synchronized long skip(long n) throws IOException { |
|
52 |
if(n < 0) { |
|
53 |
throw new IOException("can't skip negative number of bytes"); |
|
54 |
} |
|
55 |
if(recording == false) { |
|
56 |
return innerStream.skip(n); |
|
57 |
} |
|
58 |
long nskipped = 0; |
|
59 |
while(n > Integer.MAX_VALUE) { |
|
60 |
long ret = skip(Integer.MAX_VALUE); |
|
61 |
nskipped += ret; |
|
62 |
if(ret < Integer.MAX_VALUE) { |
|
63 |
return nskipped; |
|
64 |
} |
|
65 |
n -= ret; |
|
66 |
} |
|
67 |
int toread = (int)n, actuallyread = 0; |
|
68 |
byte[] buf = new byte[10240]; |
|
69 |
while(toread > 0) { |
|
70 |
int r = Math.min(toread, buf.length); |
|
71 |
int rret = this.read(buf, 0, r); |
|
72 |
actuallyread += rret; |
|
73 |
toread -= rret; |
|
74 |
if(rret < r) { |
|
75 |
break; |
|
76 |
} |
|
77 |
} |
|
78 |
return actuallyread; |
|
79 |
} |
|
80 |
public synchronized int available() throws IOException { |
|
81 |
return innerStream.available(); |
|
82 |
} |
|
83 |
public synchronized void close() throws IOException { |
|
84 |
innerStream.close(); |
|
85 |
} |
|
86 |
public synchronized void mark(int readlimit) { |
|
87 |
innerStream.mark(readlimit); |
|
88 |
} |
|
89 |
public synchronized void reset() throws IOException { |
|
90 |
innerStream.reset(); |
|
91 |
} |
|
92 |
public boolean markSupported() { |
|
93 |
return innerStream.markSupported(); |
|
94 |
} |
|
95 |
/** |
|
96 |
* If not currently recording, start recording. If the stream is currently recording, |
|
97 |
* the current buffer is cleared. |
|
98 |
*/ |
|
99 |
public synchronized void record() { |
|
100 |
recording = true; |
|
101 |
baos = new ByteArrayOutputStream(); |
|
102 |
} |
|
103 |
/** |
|
104 |
* Stops recording and clears the internal buffer. If recording is not active, an |
|
105 |
* IOException is thrown. |
|
106 |
* |
|
107 |
* @throws IOException if recording is not currently active |
|
108 |
*/ |
|
109 |
public synchronized void stopRecording() throws IOException { |
|
110 |
if(recording == false) { |
|
111 |
throw new IOException("recording not active"); |
|
112 |
} |
|
113 |
try { |
|
114 |
baos.close(); |
|
115 |
} catch (IOException ignore) {} |
|
116 |
baos = null; |
|
117 |
recording = false; |
|
118 |
} |
|
119 |
/** |
|
120 |
* Returns the data recorded so far; if recording is not active, an empty buffer |
|
121 |
* is returned. |
|
122 |
*/ |
|
123 |
public synchronized byte[] getRecordedData() { |
|
124 |
if(recording == false) { |
|
125 |
return new byte[0]; |
|
126 |
} |
|
127 |
return baos.toByteArray(); |
|
128 |
} |
|
129 |
} |
project/Deserializer/src/jdeserialize/ValidityException.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
|
|
4 |
/** |
|
5 |
* Exception that denotes that data in the stream did not conform to the constraints |
|
6 |
* imposed by the specification. |
|
7 |
*/ |
|
8 |
public class ValidityException extends IOException { |
|
9 |
public static final long serialVersionUID = 2277356908919241L; |
|
10 |
public ValidityException(String msg) { |
|
11 |
super(msg); |
|
12 |
} |
|
13 |
} |
|
14 |
|
project/Deserializer/src/jdeserialize/arraycoll.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.util.*; |
|
3 |
|
|
4 |
/** |
|
5 |
* <p>Typed collection used for storing the values of a serialized array. </p> |
|
6 |
* |
|
7 |
* <p>Primitive types are stored using their corresponding objects; for instance, an int is |
|
8 |
* stored as an Integer. To determine whether or not this is an array of ints or of |
|
9 |
* Integer instances, check the name in the arrayobj's class description.</p> |
|
10 |
*/ |
|
11 |
public class arraycoll extends ArrayList<Object> { |
|
12 |
public static final long serialVersionUID = 2277356908919248L; |
|
13 |
|
|
14 |
private fieldtype ftype; |
|
15 |
|
|
16 |
/** |
|
17 |
* Constructor. |
|
18 |
* @param ft field type of the array |
|
19 |
*/ |
|
20 |
public arraycoll(fieldtype ft) { |
|
21 |
super(); |
|
22 |
this.ftype = ft; |
|
23 |
} |
|
24 |
|
|
25 |
/** |
|
26 |
* Gets the field type of the array. |
|
27 |
* |
|
28 |
* @return the field type of the array |
|
29 |
*/ |
|
30 |
public fieldtype getFieldType() { |
|
31 |
return ftype; |
|
32 |
} |
|
33 |
public String toString() { |
|
34 |
StringBuffer sb = new StringBuffer(); |
|
35 |
sb.append("[arraycoll sz ").append(this.size()); |
|
36 |
boolean first = true; |
|
37 |
for(Object o: this) { |
|
38 |
if(first) { |
|
39 |
first = false; |
|
40 |
sb.append(' '); |
|
41 |
} else { |
|
42 |
sb.append(", "); |
|
43 |
} |
|
44 |
sb.append(o.toString()); |
|
45 |
} |
|
46 |
return sb.toString(); |
|
47 |
} |
|
48 |
} |
project/Deserializer/src/jdeserialize/arrayobj.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
/** |
|
4 |
* <p>Represents an array instance, including the values the comprise the array. </p> |
|
5 |
* |
|
6 |
* <p>Note that in arrays of primitives, the classdesc will be named "[x", where x is the |
|
7 |
* field type code representing the primitive type. See jdeserialize.resolveJavaType() |
|
8 |
* for an example of analysis/generation of human-readable names from these class names.</p> |
|
9 |
*/ |
|
10 |
public class arrayobj extends contentbase { |
|
11 |
/** |
|
12 |
* Type of the array instance. |
|
13 |
*/ |
|
14 |
public classdesc classdesc; |
|
15 |
|
|
16 |
/** |
|
17 |
* Values of the array, in the order they were read from the stream. |
|
18 |
*/ |
|
19 |
public arraycoll data; |
|
20 |
|
|
21 |
public arrayobj(int handle, classdesc cd, arraycoll data) { |
|
22 |
super(contenttype.ARRAY); |
|
23 |
this.handle = handle; |
|
24 |
this.classdesc = cd; |
|
25 |
this.data = data; |
|
26 |
} |
|
27 |
public String toString() { |
|
28 |
return "[array " + jdeserialize.hex(handle) + " classdesc " + classdesc.toString() + ": " |
|
29 |
+ data.toString() + "]"; |
|
30 |
} |
|
31 |
} |
|
32 |
|
project/Deserializer/src/jdeserialize/blockdata.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
/** |
|
4 |
* Represents an opaque block of data written to the stream. Primarily, these are used to |
|
5 |
* write class and object annotations by ObjectOutputStream overrides; they can also occur |
|
6 |
* inside an object, when the object overrides Serializable.writeObject(). Their |
|
7 |
* interpretation is hereby left to users. |
|
8 |
*/ |
|
9 |
public class blockdata extends contentbase { |
|
10 |
/** |
|
11 |
* The block data read from the stream. |
|
12 |
*/ |
|
13 |
public byte[] buf; |
|
14 |
|
|
15 |
/** |
|
16 |
* Constructor. |
|
17 |
* |
|
18 |
* @param buf the block data |
|
19 |
*/ |
|
20 |
public blockdata(byte[] buf) { |
|
21 |
super(contenttype.BLOCKDATA); |
|
22 |
this.buf = buf; |
|
23 |
} |
|
24 |
public String toString() { |
|
25 |
return "[blockdata " + jdeserialize.hex(handle) + ": " + buf.length + " bytes]"; |
|
26 |
} |
|
27 |
} |
project/Deserializer/src/jdeserialize/classdesc.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p> |
|
7 |
* Represents the entire serialized prototype of the class, including all fields, |
|
8 |
* inner classes, class annotations, and inheritance hierarchy. This includes proxy class |
|
9 |
* descriptions. |
|
10 |
* </p> |
|
11 |
* |
|
12 |
* <p> |
|
13 |
* Generally, this class is used to represent the type of an instance written to an |
|
14 |
* ObjectOutputStream with its writeObject() method, or of a related array or field type. |
|
15 |
* However, there's a notable exception: when instances of type java.io.ObjectStreamClass |
|
16 |
* are written with writeObject(), only their class description is written (cf. Object |
|
17 |
* Serialization Specification, 4.3). They will be represented with an instance of |
|
18 |
* classdesc as well. |
|
19 |
* </p> |
|
20 |
*/ |
|
21 |
public class classdesc extends contentbase { |
|
22 |
/** |
|
23 |
* Type of the class being represented; either a normal class or a proxy class. |
|
24 |
*/ |
|
25 |
public classdesctype classtype; |
|
26 |
|
|
27 |
/** |
|
28 |
* Class name. |
|
29 |
*/ |
|
30 |
public String name; |
|
31 |
|
|
32 |
/** |
|
33 |
* Serial version UID, as recorded in the stream. |
|
34 |
*/ |
|
35 |
public long serialVersionUID; |
|
36 |
|
|
37 |
/** |
|
38 |
* Description flags byte; this should be a mask of values from the ObjectStreamContants |
|
39 |
* class. Refer to chapter 6 of the Object Stream Serialization Protocol for details. |
|
40 |
*/ |
|
41 |
public byte descflags; |
|
42 |
|
|
43 |
/** |
|
44 |
* Array of fields in the class, in the order serialized by the stream writer. |
|
45 |
*/ |
|
46 |
public field[] fields; |
|
47 |
|
|
48 |
/** |
|
49 |
* List of inner classes, in the order serialized by the stream writer. |
|
50 |
*/ |
|
51 |
public List<classdesc> innerclasses; |
|
52 |
|
|
53 |
/** |
|
54 |
* List of annotation objects; these are *not* Java annotations, but data written by |
|
55 |
* the <pre>annotateClass(Class<?>)<pre> and <pre>annotateProxyClass(Class<?>)</pre> methods of an |
|
56 |
* ObjectOutputStream. |
|
57 |
*/ |
|
58 |
public List<content> annotations; |
|
59 |
|
|
60 |
/** |
|
61 |
* The superclass of the object, if available. |
|
62 |
*/ |
|
63 |
public classdesc superclass; |
|
64 |
|
|
65 |
/** |
|
66 |
* Array of serialized interfaces, in the order serialized by the stream writer. |
|
67 |
*/ |
|
68 |
public String[] interfaces; |
|
69 |
|
|
70 |
/** |
|
71 |
* Set of enum constants, for enum classes. |
|
72 |
*/ |
|
73 |
public Set<String> enumconstants; |
|
74 |
|
|
75 |
private boolean isInnerClass = false; |
|
76 |
/** |
|
77 |
* True if this class has been determined to be an inner class; this determination is |
|
78 |
* generally made by connectMemberClasses(). |
|
79 |
* |
|
80 |
* @return true if the class is an inner class |
|
81 |
*/ |
|
82 |
public boolean isInnerClass() { |
|
83 |
return isInnerClass; |
|
84 |
} |
|
85 |
/** |
|
86 |
* Sets the value that denotes that the class is an inner class. |
|
87 |
* |
|
88 |
* @param nis the value to set |
|
89 |
*/ |
|
90 |
public void setIsInnerClass(boolean nis) { |
|
91 |
this.isInnerClass = nis; |
|
92 |
} |
|
93 |
|
|
94 |
private boolean isLocalInnerClass = false; |
|
95 |
/** |
|
96 |
* True if this class has been determined to be a local inner class; this |
|
97 |
* determination is generally made by connectMemberClasses(). |
|
98 |
* |
|
99 |
* @return true if the class is a local inner class |
|
100 |
*/ |
|
101 |
public boolean isLocalInnerClass() { |
|
102 |
return isLocalInnerClass; |
|
103 |
} |
|
104 |
/** |
|
105 |
* Sets the flag that denotes whether this class is a local inner class. |
|
106 |
* |
|
107 |
* @param nis the value to set |
|
108 |
*/ |
|
109 |
public void setIsLocalInnerClass(boolean nis) { |
|
110 |
this.isLocalInnerClass = nis; |
|
111 |
} |
|
112 |
|
|
113 |
private boolean isStaticMemberClass = false; |
|
114 |
/** |
|
115 |
* <p> |
|
116 |
* True if this class has been determined to be a static member class; this |
|
117 |
* determination is generally made by connectMemberClasses(). |
|
118 |
* </p> |
|
119 |
* |
|
120 |
* <p> |
|
121 |
* Note that in some cases, static member classes' descriptions will be serialized |
|
122 |
* even though their enclosing class is not. In these cases, this may return false. |
|
123 |
* See connectMemberClasses() for details. |
|
124 |
* </p> |
|
125 |
* |
|
126 |
* @return true if this is a static member class |
|
127 |
*/ |
|
128 |
public boolean isStaticMemberClass() { |
|
129 |
return isStaticMemberClass; |
|
130 |
} |
|
131 |
/** |
|
132 |
* Sets the flag that denotes whether this class is a static member class. |
|
133 |
* |
|
134 |
* @param nis the value to set |
|
135 |
*/ |
|
136 |
public void setIsStaticMemberClass(boolean nis) { |
|
137 |
this.isStaticMemberClass = nis; |
|
138 |
} |
|
139 |
|
|
140 |
/** |
|
141 |
* Constructor. |
|
142 |
* |
|
143 |
* @param classtype the type of the class |
|
144 |
*/ |
|
145 |
public classdesc(classdesctype classtype) { |
|
146 |
super(contenttype.CLASSDESC); |
|
147 |
this.classtype = classtype; |
|
148 |
this.enumconstants = new HashSet<String>(); |
|
149 |
this.innerclasses = new ArrayList<classdesc>(); |
|
150 |
} |
|
151 |
|
|
152 |
/** |
|
153 |
* Add an inner class to the description's list. |
|
154 |
* @param cd inner class to add |
|
155 |
*/ |
|
156 |
public void addInnerClass(classdesc cd) { |
|
157 |
innerclasses.add(cd); |
|
158 |
} |
|
159 |
|
|
160 |
/** |
|
161 |
* Add an enum constant to the description's set. |
|
162 |
* |
|
163 |
* @param constval enum constant string |
|
164 |
*/ |
|
165 |
public void addEnum(String constval) { |
|
166 |
this.enumconstants.add(constval); |
|
167 |
} |
|
168 |
|
|
169 |
/** |
|
170 |
* Determines whether this is an array type. |
|
171 |
* @return true if this is an array type. |
|
172 |
*/ |
|
173 |
public boolean isArrayClass() { |
|
174 |
if(name != null && name.length() > 1 && name.charAt(0) == '[') { |
|
175 |
return true; |
|
176 |
} else { |
|
177 |
return false; |
|
178 |
} |
|
179 |
} |
|
180 |
public String toString() { |
|
181 |
StringBuffer sb = new StringBuffer(); |
|
182 |
sb.append("[cd ").append(jdeserialize.hex(handle)).append(": name ").append(name); |
|
183 |
sb.append(" uid ").append(serialVersionUID); |
|
184 |
sb.append("]"); |
|
185 |
return sb.toString(); |
|
186 |
} |
|
187 |
|
|
188 |
/** |
|
189 |
* Generates a list of all class descriptions in this class's hierarchy, in the order |
|
190 |
* described by the Object Stream Serialization Protocol. This is the order in which |
|
191 |
* fields are read from the stream. |
|
192 |
* |
|
193 |
* @param classes a list to be filled in with the hierarchy |
|
194 |
*/ |
|
195 |
public void getHierarchy(ArrayList<classdesc> classes) { |
|
196 |
if(superclass != null) { |
|
197 |
if(superclass.classtype == classdesctype.PROXYCLASS) { |
|
198 |
jdeserialize.debugerr("warning: hit a proxy class in superclass hierarchy"); |
|
199 |
} else { |
|
200 |
superclass.getHierarchy(classes); |
|
201 |
} |
|
202 |
} |
|
203 |
classes.add(this); |
|
204 |
} |
|
205 |
public void validate() throws ValidityException { |
|
206 |
// If neither SC_SERIALIZABLE nor SC_EXTERNALIZABLE is set, then the number of |
|
207 |
// fields is always zero. (spec section 4.3) |
|
208 |
if((descflags & (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) == 0 && fields != null && fields.length > 0) { |
|
209 |
throw new ValidityException("non-serializable, non-externalizable class has fields!"); |
|
210 |
} |
|
211 |
if((descflags & (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) == (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) { |
|
212 |
throw new ValidityException("both Serializable and Externalizable are set!"); |
|
213 |
} |
|
214 |
if((descflags & ObjectStreamConstants.SC_ENUM) != 0) { |
|
215 |
// we're an enum; shouldn't have any fields/superinterfaces |
|
216 |
if((fields != null && fields.length > 0) || interfaces != null) { |
|
217 |
throw new ValidityException("enums shouldn't implement interfaces or have non-constant fields!"); |
|
218 |
} |
|
219 |
} else { |
|
220 |
// non-enums shouldn't have enum constant fields. |
|
221 |
if(enumconstants != null && enumconstants.size() > 0) { |
|
222 |
throw new ValidityException("non-enum classes shouldn't have enum constants!"); |
|
223 |
} |
|
224 |
} |
|
225 |
} |
|
226 |
} |
|
227 |
|
project/Deserializer/src/jdeserialize/classdesctype.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
/** |
|
4 |
* Enum for class description types. |
|
5 |
*/ |
|
6 |
public enum classdesctype { |
|
7 |
NORMALCLASS, PROXYCLASS |
|
8 |
} |
project/Deserializer/src/jdeserialize/classobj.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
/** |
|
4 |
* This represents a Class object (i.e. an instance of type Class) serialized in the |
|
5 |
* stream. |
|
6 |
*/ |
|
7 |
public class classobj extends contentbase { |
|
8 |
/** |
|
9 |
* The class description, including its name. |
|
10 |
*/ |
|
11 |
public classdesc classdesc; |
|
12 |
|
|
13 |
/** |
|
14 |
* Constructor. |
|
15 |
* |
|
16 |
* @param handle the instance's handle |
|
17 |
* @param cd the instance's class description |
|
18 |
*/ |
|
19 |
public classobj(int handle, classdesc cd) { |
|
20 |
super(contenttype.CLASS); |
|
21 |
this.handle = handle; |
|
22 |
this.classdesc = cd; |
|
23 |
} |
|
24 |
public String toString() { |
|
25 |
return "[class " + jdeserialize.hex(handle) + ": " + classdesc.toString() + "]"; |
|
26 |
} |
|
27 |
} |
|
28 |
|
project/Deserializer/src/jdeserialize/content.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
/** |
|
4 |
* <p> |
|
5 |
* Generic interface for all data that may be read from the stream (except null). |
|
6 |
* </p> |
|
7 |
* |
|
8 |
* <p> |
|
9 |
* A successful read of the stream will result in a series of content instances or null |
|
10 |
* references. For details on specific metadata, see documentation on implementing |
|
11 |
* classes/subinterfaces. |
|
12 |
* </p> |
|
13 |
*/ |
|
14 |
public interface content { |
|
15 |
/** |
|
16 |
* @return the type of instance represented by this object. |
|
17 |
*/ |
|
18 |
public contenttype getType(); |
|
19 |
|
|
20 |
/** |
|
21 |
* <p> |
|
22 |
* Get the numeric handle by which this object was referred to in the object stream. |
|
23 |
* These handles are used internally by Object{Output,Input}Stream as a mechanism to |
|
24 |
* avoid costly duplication. |
|
25 |
* </p> |
|
26 |
* |
|
27 |
* <p> |
|
28 |
* CAUTION: they are *not* necessarily unique across all objects in a given stream! |
|
29 |
* If an exception was thrown during serialization (which is most likely to happen |
|
30 |
* during a serialized objct's writeObject() implementation), then the stream resets |
|
31 |
* before and after the exception is serialized. |
|
32 |
* </p> |
|
33 |
* |
|
34 |
* @return the handle assigned in the stream |
|
35 |
*/ |
|
36 |
public int getHandle(); |
|
37 |
|
|
38 |
/** |
|
39 |
* Performs extra object-specific validity checks. |
|
40 |
* |
|
41 |
* @throws ValidityException if the object's state is invalid |
|
42 |
*/ |
|
43 |
public void validate() throws ValidityException; |
|
44 |
|
|
45 |
/** |
|
46 |
* <p> |
|
47 |
* Tells whether or not this object is an exception that was caught during |
|
48 |
* serialization. |
|
49 |
* </p> |
|
50 |
* |
|
51 |
* <p> |
|
52 |
* <b>Note</b>: Not every Throwable or Exception in the stream will have this flag set to |
|
53 |
* true; only those which were thrown <i>during serialization</i> will |
|
54 |
* </p> |
|
55 |
* |
|
56 |
* @return true iff the object was an exception thrown during serialization |
|
57 |
*/ |
|
58 |
public boolean isExceptionObject(); |
|
59 |
|
|
60 |
/** |
|
61 |
* Sets the flag that tells whether or not this object is an exception that was caught |
|
62 |
* during serialization. |
|
63 |
* |
|
64 |
* @param value the new value to use |
|
65 |
*/ |
|
66 |
public void setIsExceptionObject(boolean value); |
|
67 |
} |
|
68 |
|
project/Deserializer/src/jdeserialize/contentbase.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
/** |
|
4 |
* Provides a skeleton content implementation. |
|
5 |
*/ |
|
6 |
public class contentbase implements content { |
|
7 |
public int handle; |
|
8 |
public boolean isExceptionObject; |
|
9 |
protected contenttype type; |
|
10 |
public contentbase(contenttype type) { |
|
11 |
this.type = type; |
|
12 |
} |
|
13 |
public boolean isExceptionObject() { |
|
14 |
return isExceptionObject; |
|
15 |
} |
|
16 |
public void setIsExceptionObject(boolean value) { |
|
17 |
isExceptionObject = value; |
|
18 |
} |
|
19 |
public contenttype getType() { |
|
20 |
return type; |
|
21 |
} |
|
22 |
public int getHandle() { |
|
23 |
return this.handle; |
|
24 |
} |
|
25 |
public void validate() throws ValidityException { |
|
26 |
} |
|
27 |
} |
|
28 |
|
project/Deserializer/src/jdeserialize/contenttype.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
public enum contenttype { |
|
4 |
INSTANCE, CLASS, ARRAY, STRING, ENUM, CLASSDESC, BLOCKDATA, EXCEPTIONSTATE |
|
5 |
} |
project/Deserializer/src/jdeserialize/enumobj.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
/** |
|
4 |
* <p> |
|
5 |
* Represents an enum instance. As noted in the serialization spec, this consists of |
|
6 |
* merely the class description (represented by a classdesc) and the string corresponding |
|
7 |
* to the enum's value. No other fields are ever serialized. |
|
8 |
* </p> |
|
9 |
*/ |
|
10 |
public class enumobj extends contentbase { |
|
11 |
/** |
|
12 |
* The enum's class description. |
|
13 |
*/ |
|
14 |
public classdesc classdesc; |
|
15 |
|
|
16 |
/** |
|
17 |
* The string that represents the enum's value. |
|
18 |
*/ |
|
19 |
public stringobj value; |
|
20 |
|
|
21 |
/** |
|
22 |
* Constructor. |
|
23 |
* |
|
24 |
* @param handle the enum's handle |
|
25 |
* @param cd the enum's class description |
|
26 |
* @param so the enum's value |
|
27 |
*/ |
|
28 |
public enumobj(int handle, classdesc cd, stringobj so) { |
|
29 |
super(contenttype.ENUM); |
|
30 |
this.handle = handle; |
|
31 |
this.classdesc = cd; |
|
32 |
this.value = so; |
|
33 |
} |
|
34 |
public String toString() { |
|
35 |
return "[enum " + jdeserialize.hex(handle) + ": " + value.value + "]"; |
|
36 |
} |
|
37 |
} |
Také k dispozici: Unified diff
#7794
Vytvoření hlavního projektu.