Projekt

Obecné

Profil

Stáhnout (5.4 KB) Statistiky
| Větev: | Tag: | Revize:
1
import java.io.File;
2
import java.io.FileDescriptor;
3
import java.io.FileOutputStream;
4
import java.io.PrintStream;
5
import java.util.List;
6
import java.util.concurrent.Semaphore;
7
import java.util.concurrent.atomic.AtomicBoolean;
8
import java.util.concurrent.atomic.AtomicReference;
9
import java.util.concurrent.locks.Lock;
10
import java.util.concurrent.locks.ReentrantLock;
11

    
12
import jdeserialize.content;
13
import jdeserialize.jdeserialize;
14
import io.Database.DB_Messenger;
15
import io.Database;
16
import io.FileWorker;
17

    
18
/**
19
 * An instance of this class is a thread for converting an input file or SQL
20
 * query to the resulting JSON.
21
 */
22
public class Converter extends Thread {
23

    
24
	/**
25
	 * The user interface that this thread created.
26
	 */
27
	private IConversionResults ui;
28

    
29
	/**
30
	 * True, if thread is active, otherwise false. Thread-safe variable.
31
	 */
32
	private AtomicBoolean active;
33

    
34
	/**
35
	 * "Mutex" for the producer–consumer.
36
	 */
37
	private Lock entryLock;
38

    
39
	/**
40
	 * Semaphore for the existence of an input requirement (producer-consumer).
41
	 */
42
	private Semaphore inputAvailable;
43

    
44
	/**
45
	 * Variable for input file. Set by the user.
46
	 */
47
	private File inputFile;
48

    
49
	/**
50
	 * Variable for SQL query. Set by the user.
51
	 */
52
	private DB_Messenger query;
53

    
54
	/**
55
	 * Initializes instance attributes.
56
	 * 
57
	 * @param ui instance of the Window or CLI.
58
	 */
59
	public Converter(IConversionResults ui) {
60
		this.ui = ui;
61
		active = new AtomicBoolean(true);
62
		entryLock = new ReentrantLock();
63
		inputAvailable = new Semaphore(0);
64
	}
65

    
66
	/**
67
	 * End of the thread run.
68
	 */
69
	public void end() {
70
		active.set(false);
71
		setInput(null, null);
72
	}
73

    
74
	/**
75
	 * Sets the input processing request. One of the input parameters should be
76
	 * null.
77
	 * 
78
	 * @param inputFile input file.
79
	 * @param query     SQL query.
80
	 */
81
	public void setInput(File inputFile, DB_Messenger query) {
82
		entryLock.lock();
83
		this.inputFile = inputFile;
84
		this.query = query;
85
		entryLock.unlock();
86

    
87
		if (!inputAvailable.tryAcquire())
88
			inputAvailable.release(); // MAX VALUE = 1!
89
	}
90

    
91
	/**
92
	 * Get a request to process the input.
93
	 * 
94
	 * @param inputFile variable for input file "passing by reference".
95
	 * @param query     variable for SQL query "passing by reference".
96
	 * 
97
	 * @return true, when there is a request to process the input.
98
	 */
99
	public boolean getInput(AtomicReference<File> inputFile, AtomicReference<DB_Messenger> query) {
100
		try {
101
			inputAvailable.acquire();
102
		} catch (InterruptedException e) {
103
			return false;
104
		}
105

    
106
		entryLock.lock();
107
		inputFile.set(this.inputFile);
108
		query.set(this.query);
109

    
110
		this.inputFile = null;
111
		this.query = null;
112
		entryLock.unlock();
113

    
114
		return inputFile.get() != null || query.get() != null;
115
	}
116

    
117
	@Override
118
	public void run() {
119
		super.run();
120
		while (active.get()) {
121
			AtomicReference<File> inputFile = new AtomicReference<File>();
122
			AtomicReference<DB_Messenger> query = new AtomicReference<DB_Messenger>();
123

    
124
			// Get input data from the user.
125
			if (!getInput(inputFile, query)) {
126
				// If there is no data, continue.
127
				continue;
128
			}
129

    
130
			// Get the byte array from the input.
131
			byte array[];
132
			try {
133
				array = getBytes(inputFile.get(), query.get());
134
			} catch (Exception e) {
135
				// If an error occurs, it informs the user interface and continues.
136
				ui.loadingInputFileError();
137
				continue;
138
			}
139

    
140
			// Deserialization of read data.
141
			StringBuilder json = new StringBuilder();
142
			boolean error = false;
143
			try {
144
				// Redirection of System.out to jdeserialize log file
145
				System.setOut(FileWorker.createRedirectStream(false));
146
				System.setErr(FileWorker.createRedirectStream(true));
147
				System.out.println("--- jdeserialize begins ---".toUpperCase());
148
				convert(array, json);
149
			} catch (Exception e) {
150
				e.printStackTrace();
151
				error = true;
152
			} finally {
153
				System.out.println("--- jdeserialize ends ---".toUpperCase());
154
				System.out.flush();
155
				System.err.flush();
156
				System.setErr(new PrintStream(new FileOutputStream(FileDescriptor.err)));
157
				System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
158
			}
159

    
160
			// Pass the deserialization results to the UI.
161
			ui.completed(error ? null : json.toString(), array == null ? null : new String(array));
162
		}
163
	}
164

    
165
	/**
166
	 * Retrieve data from the file or database. One parameter should always be null.
167
	 * 
168
	 * @param file  input file.
169
	 * @param query input query.
170
	 * 
171
	 * @return read data in a byte array.
172
	 * @throws Exception if an error occurs while retrieving data.
173
	 */
174
	private byte[] getBytes(File file, DB_Messenger query) throws Exception {
175
		byte array[];
176
		if (file != null) {
177
			array = FileWorker.loadFileContent(file);
178
		} else {
179
			array = Database.getBlobBytes(query);
180
		}
181
		array = FileWorker.extractFileContent(array);
182
		return array;
183
	}
184

    
185
	/**
186
	 * Converts the input byte buffer given by parameter into json which is saved
187
	 * using the StringBuilder.
188
	 * 
189
	 * @param buffer byte array buffer for input data of serialized object.
190
	 * @param json   StringBuilder to which will be saved the json result.
191
	 * 
192
	 * @throws Exception if an error occurred during deserialization.
193
	 */
194
	private void convert(byte[] buffer, StringBuilder json) throws Exception {
195
		jdeserialize deserializer = new jdeserialize(buffer);
196

    
197
		// gets the "contents" into an array - returns the deserialization of all
198
		// 'writes' into serialized object via objectOutputStream
199
		List<content> cntnts = deserializer.getContent();
200

    
201
		for (content cnt : cntnts) {
202
			if (cnt != null) {
203
				json.append(cnt.toJson("", null, false)).append("\n");
204
			}
205
		}
206
	}
207

    
208
}
(2-2/6)