Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Eric Duminil
RegionChooser
Commits
0f1c41b0
Commit
0f1c41b0
authored
May 27, 2015
by
duminil
Browse files
novaFactory : Saving file to TmpFolder
parent
6eac4c9f
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/eu/simstadt/nf4j/async/AsyncExportJob.java
View file @
0f1c41b0
...
...
@@ -4,71 +4,72 @@
import
java.util.LinkedList
;
import
java.util.Objects
;
import
java.util.Optional
;
import
eu.simstadt.nf4j.Connector
;
import
eu.simstadt.nf4j.ExportJob
;
import
eu.simstadt.nf4j.FailedTransmissionException
;
import
eu.simstadt.nf4j.InvalidJobDescriptorException
;
import
eu.simstadt.nf4j.JobStatus
;
import
eu.simstadt.nf4j.Connector
;
/**
* Export jobs are requests for CityGML models. Every valid export job has an id and a status. This implementation
* offers non-blocking asynchronous send, poll and download operations, so that your main application has not to
*
wait
for the results. You may want to register your main application as a job status listeners at this job to
*
get status
updates from the asynchronous operations.
* offers non-blocking asynchronous send, poll and download operations, so that your main application has not to
wait
* for the results. You may want to register your main application as a job status listeners at this job to
get status
* updates from the asynchronous operations.
*
* @author Marcel Bruse
*/
public
class
AsyncExportJob
extends
ExportJob
<
ExportJobDescription
>
implements
AsyncJob
{
public
class
AsyncExportJob
extends
ExportJob
<
ExportJobDescription
>
implements
AsyncJob
{
/**
* While polling for the current job status, the polling thread will sleep for this amount of seconds
*
before each
status update request.
* While polling for the current job status, the polling thread will sleep for this amount of seconds
before each
* status update request.
*/
private
final
int
DEFAULT_POLLING_INTERVAL
=
5
;
// seconds
/** There can only be one sending thread for each job at a time. */
private
Thread
sendThread
;
/** There can only be one polling thread for each job at a time. */
private
Thread
pollThread
;
/** There can only be one download thread for each job at a time. */
private
Thread
downloadThread
;
/**
* Once the send() operation has been triggered, this member will be true. No subsequent invocations of
*
send() will
be possible then.
/**
* Once the send() operation has been triggered, this member will be true. No subsequent invocations of
send() will
* be possible then.
*/
private
boolean
jobTransmissionTriggered
=
false
;
/** As long as this variable is true, the polling thread will be kept alive. */
private
boolean
keepPolling
=
true
;
/**
* List of all registered job status listeners. Whenever the state of this job changes, these listeners
*
will get
informed.
/**
* List of all registered job status listeners. Whenever the state of this job changes, these listeners
will get
* informed.
*/
private
LinkedList
<
JobStatusListener
>
jobListenerList
=
new
LinkedList
<>();
/**
* This job will be send and observed asynchronously. It
'
s results will be downloaded asynchronously also.
*
If an
asynchronous operation breaks, then the last encountered problem will be described here.
* This job will be send and observed asynchronously. Its results will be downloaded asynchronously also.
If an
* asynchronous operation breaks, then the last encountered problem will be described here.
*/
private
Optional
<
String
>
lastEncounteredProblem
=
Optional
.
empty
();
/**
* The last job status which has been sent to all registered job status listeners.
*/
private
JobStatus
lastPublishedJobStatus
;
/** Once the CityGML file has been download, it should be referenced here. */
private
File
result
;
private
File
result
;
/**
* This constructor forces the job to have a description and a connector instance. Every job which
*
is created by this
constructor will have the status "local", because it is assumed that it has an unsent
*
description and no job id
yet.
* This constructor forces the job to have a description and a connector instance. Every job which
is created by this
* constructor will have the status "local", because it is assumed that it has an unsent
description and no job id
* yet.
*
* @param connector The job will use this connector to synchronize itself with the nF.
* @param descriptor The description of this job.
...
...
@@ -80,21 +81,21 @@ public AsyncExportJob(ExportJobDescription descriptor, Connector<AsyncImportJob,
/**
* This constructor forces the job to have a id and a connector instance. Every job which is created by this
* constructor will have the status "sent", because it is assumed that the job is already enqueued at the
*
nF job
queue.
* constructor will have the status "sent", because it is assumed that the job is already enqueued at the
nF job
* queue.
*
* @param id The job id. If you call updateStatus() and the nF "knows" the job id, then the job status
*
will be
updated. If you call updateStatus() and the job id is "unkown" on the server side, then
* @param id The job id. If you call updateStatus() and the nF "knows" the job id, then the job status
will be
*
updated. If you call updateStatus() and the job id is "unkown" on the server side, then
* @param connector The job will use this connector to synchronize itself with the nF.
*/
public
AsyncExportJob
(
int
id
,
Connector
<
AsyncImportJob
,
AsyncExportJob
>
connector
)
{
super
(
id
,
connector
);
status
=
JobStatus
.
SENT
;
}
/**
* Builds an XML job file from the job description and sends it to the nF server which has been configured
*
in your
connector instance. This will be done asynchronously within a SendExportJobTask.
* Builds an XML job file from the job description and sends it to the nF server which has been configured
in your
* connector instance. This will be done asynchronously within a SendExportJobTask.
*
* @throws FailedTransmissionException If this method has been called before, then you will receive this.
* @throws InvalidJobDescriptorException If the job description is invalid or null, then you will receive this.
...
...
@@ -112,19 +113,18 @@ public synchronized void send() throws FailedTransmissionException, InvalidJobDe
sendThread
=
new
Thread
(
new
SendExportJobTask
(
this
));
sendThread
.
start
();
}
/**
* Frequently queries the status of the remote nF export job and updates the local status accordingly.
*
The queries
will be performed asynchronously in a separate thread. Job status listeners will be notified
*
upon every new status
change.
* Frequently queries the status of the remote nF export job and updates the local status accordingly.
The queries
* will be performed asynchronously in a separate thread. Job status listeners will be notified
upon every new status
* change.
*
* Note, there can only be one polling thread at a time. Subsequent calls of poll() will stop the previously
*
started
poll threads.
* Note, there can only be one polling thread at a time. Subsequent calls of poll() will stop the previously
started
* poll threads.
*
* @param interval Amount of seconds to wait before the next status update request will be sent to the
* nF server.
* @param interval Amount of seconds to wait before the next status update request will be sent to the nF server.
*
* @throws FailedTransmissionException If your job has not been sent yet, then you will get some of this.
* @throws FailedTransmissionException If your job has not been sent yet, then you will get some of this.
*/
@Override
public
synchronized
void
poll
(
int
interval
)
throws
FailedTransmissionException
{
...
...
@@ -138,33 +138,32 @@ public synchronized void poll(int interval) throws FailedTransmissionException {
pollThread
=
new
Thread
(
new
PollJobStatusTask
(
this
,
interval
));
pollThread
.
start
();
}
/**
* Convenience method for polling with a predefined default interval.
*
* Frequently queries the status of the remote nF export job and updates the local status accordingly.
*
The queries
will be performed asynchronously in a separate thread. Job status listeners will be notified
*
upon every new status
change.
* Frequently queries the status of the remote nF export job and updates the local status accordingly.
The queries
* will be performed asynchronously in a separate thread. Job status listeners will be notified
upon every new status
* change.
*
* Note, there can only be one polling thread at a time. Subsequent calls of poll() will stop the previously
*
started
poll threads.
* Note, there can only be one polling thread at a time. Subsequent calls of poll() will stop the previously
started
* poll threads.
*
* @param interval Amount of seconds to wait before the next status update request will be sent to the
* nF server.
* @throws FailedTransmissionException If your job has not been sent yet, then you will get some of this.
* @param interval Amount of seconds to wait before the next status update request will be sent to the nF server.
* @throws FailedTransmissionException If your job has not been sent yet, then you will get some of this.
* @see poll(int)
*/
public
synchronized
void
poll
()
throws
FailedTransmissionException
{
poll
(
DEFAULT_POLLING_INTERVAL
);
}
/**
* Connects to the nF and refreshes the status of this job. If there is no nF connector set,
*
this operation will
throw a FailedTransmissionException.
* Connects to the nF and refreshes the status of this job. If there is no nF connector set,
this operation will
* throw a FailedTransmissionException.
*
* @throws FailedTransmissionException You will receive this exception if no connector is present, the connection
*
to
the nF is broken, the job has not been sent to the nF yet, or another update request is ongoing. In the
two
* latter cases, job will either have the status "LOCAL" or "WAITING".
* @throws FailedTransmissionException You will receive this exception if no connector is present, the connection
to
*
the nF is broken, the job has not been sent to the nF yet, or another update request is ongoing. In the
*
two
latter cases, job will either have the status "LOCAL" or "WAITING".
*/
@Override
public
synchronized
void
updateStatus
()
throws
FailedTransmissionException
{
...
...
@@ -180,10 +179,10 @@ public synchronized void updateStatus() throws FailedTransmissionException {
setStatus
(
job
.
getStatus
(),
Optional
.
empty
());
}
}
/**
* Calls updateStatus() for you, since updateStatus() is a protected method. This method is used by the
*
asynchronous
PollJobStatusTask class.
* Calls updateStatus() for you, since updateStatus() is a protected method. This method is used by the
asynchronous
* PollJobStatusTask class.
*/
@Override
public
void
triggerStatusUpdate
()
throws
FailedTransmissionException
{
...
...
@@ -191,57 +190,60 @@ public void triggerStatusUpdate() throws FailedTransmissionException {
}
/**
* Sets the status of this job depending on the given nF status code. nF status codes will be sent
*
to you in http
responses.
*
* Sets the status of this job depending on the given nF status code. nF status codes will be sent
to you in http
* responses.
*
* @param statusCode The nF status code for this job.
*/
@Override
public
synchronized
void
setStatusForCode
(
int
statusCode
)
{
switch
(
statusCode
)
{
case
0
:
setStatus
(
JobStatus
.
PENDING
);
break
;
setStatus
(
JobStatus
.
PENDING
);
break
;
case
10
:
setStatus
(
JobStatus
.
RUNNING
);
break
;
setStatus
(
JobStatus
.
RUNNING
);
break
;
case
20
:
setStatus
(
JobStatus
.
FAILED
);
break
;
setStatus
(
JobStatus
.
FAILED
);
break
;
case
30
:
setStatus
(
JobStatus
.
FINISHED
);
break
;
setStatus
(
JobStatus
.
FINISHED
);
break
;
default
:
setStatus
(
JobStatus
.
UNKNOWN
);
}
}
/**
* @return Returns true, if the job is definitely done. This is also the case, if the resulting CityGML
*
file has been
download. False, otherwise.
* @return Returns true, if the job is definitely done. This is also the case, if the resulting CityGML
file has been
*
download. False, otherwise.
*/
@Override
public
boolean
hasFinished
()
{
return
status
==
JobStatus
.
FINISHED
||
status
==
JobStatus
.
DOWNLOAD
;
}
/**
* @return Returns true, if the job has been failed. You may want to look up the "last encountered problem"
* string.
* @return Returns true, if the job has been failed. You may want to look up the "last encountered problem" string.
*/
@Override
public
boolean
hasFailed
()
{
return
status
==
JobStatus
.
FAILED
;
}
/**
* Registers a job status listener.
*
* @param jobListener The job status listener to be registered. This listener will receive updates about every
* progressing change of the job status. Meaning, the change to a particular status will only be signaled
once
* to the listener.
*
progressing change of the job status. Meaning, the change to a particular status will only be signaled
*
once
to the listener.
*/
@Override
public
void
addJobStatusListener
(
JobStatusListener
jobListener
)
{
jobListenerList
.
add
(
jobListener
);
}
/**
* Unregisters a job status listener.
*
...
...
@@ -251,12 +253,11 @@ public void addJobStatusListener(JobStatusListener jobListener) {
public
void
removeJobStatusListener
(
JobStatusListener
jobListener
)
{
jobListenerList
.
remove
(
jobListener
);
}
/**
* Once the status of this job changes, all registered job status listeners will be notified.
* Listeners will only be notified of the status updates where the status of the job progresses and they will
* only be notified once about every singular status. If this status has been signaled already, then the
* listeners will not be notified again.
* Once the status of this job changes, all registered job status listeners will be notified. Listeners will only be
* notified of the status updates where the status of the job progresses and they will only be notified once about
* every singular status. If this status has been signaled already, then the listeners will not be notified again.
*/
@Override
public
synchronized
void
notifyJobStatusListeners
()
{
...
...
@@ -268,7 +269,7 @@ public synchronized void notifyJobStatusListeners() {
lastPublishedJobStatus
=
status
;
}
}
/**
* Cancels all ongoing send, poll and download operations as soon as possible.
*/
...
...
@@ -285,7 +286,7 @@ public void cancel() {
downloadThread
.
interrupt
();
}
}
/**
* @return Returns true, if the polling thread should go on with its polling job. Otherwise, false.
*/
...
...
@@ -293,14 +294,13 @@ public void cancel() {
public
boolean
keepPolling
()
{
return
keepPolling
;
}
/**
* Starts downloading the export job result, if there is any. As soon as the download has been finished,
*
the job
status will be set to DOWNLOADED. All registered job status listeners will get notified about
*
the it. Afterwards,
you may want to obtain a handle to the download CityGML file with getResult().
* Starts downloading the export job result, if there is any. As soon as the download has been finished,
the job
* status will be set to DOWNLOADED. All registered job status listeners will get notified about
the it. Afterwards,
* you may want to obtain a handle to the download CityGML file with getResult().
*
* @throws FailedTransmissionException If the job has not been finished yet, then you will get some
* of this.
* @throws FailedTransmissionException If the job has not been finished yet, then you will get some of this.
*/
public
void
downloadResult
()
throws
FailedTransmissionException
{
if
(!
hasFinished
())
{
...
...
@@ -309,50 +309,48 @@ public void downloadResult() throws FailedTransmissionException {
downloadThread
=
new
Thread
(
new
DownloadTask
(
this
));
downloadThread
.
start
();
}
/**
* This method is used by the download task to set the CityGML file handle as soon as the file has
* been download.
* This method is used by the download task to set the CityGML file handle as soon as the file has been download.
*
* @param result The file handle of the download CityGML file.
*/
protected
void
setResult
(
File
result
)
{
this
.
result
=
result
;
}
/**
* This method will return the download CityGML file for this export job, but only if the export job has
*
actually
been finished before.
* This method will return the download CityGML file for this export job, but only if the export job has
actually
* been finished before.
*
* @return Returns a file handle to the download CityGML file.
*
* @throws FailedTransmissionException If the job result has not been download yet, then you will get some
* of this.
* @throws FailedTransmissionException If the job result has not been download yet, then you will get some of this.
*/
@Override
public
File
getResult
()
throws
FailedTransmissionException
{
if
(!
hasFinished
())
{
throw
new
FailedTransmissionException
(
"Job has not been finished!"
);
throw
new
FailedTransmissionException
(
"Job has not been finished!"
);
}
if
(
Objects
.
isNull
(
result
))
{
throw
new
FailedTransmissionException
(
"Job result has not been downloaded!"
);
}
return
result
;
}
/**
* The asynchronous send, poll and download tasks cannot throw exceptions. If something goes wrong during the save,
* poll or download operation, then you may want to submit at lease a textual description of the problem here. This
* message will be sent to all registered job status listeners on the next status update. This is why you can use
*
the
convenience method setStatus(jobStatus, message), to do both at the same time.
*
* message will be sent to all registered job status listeners on the next status update. This is why you can use
the
* convenience method setStatus(jobStatus, message), to do both at the same time.
*
* @param errorMessage The description of the encountered problem. This could be the exception message or a more user
* friendly message.
*
friendly message.
*/
protected
synchronized
void
setLastEncounteredProblem
(
Optional
<
String
>
errorMessage
)
{
this
.
lastEncounteredProblem
=
errorMessage
;
}
/**
* A convenience method to set a new job status and a status message at the same time. Status messages will be passed
* by asynchronous tasks instead of exception, because they cannot throw exceptions.
...
...
@@ -365,5 +363,5 @@ protected synchronized void setStatus(JobStatus jobStatus, Optional<String> mess
lastEncounteredProblem
=
message
;
notifyJobStatusListeners
();
}
}
\ No newline at end of file
src/eu/simstadt/nf4j/async/HTTPConnection.java
View file @
0f1c41b0
...
...
@@ -19,86 +19,85 @@
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Optional
;
import
javax.xml.parsers.ParserConfigurationException
;
import
javax.xml.parsers.SAXParser
;
import
javax.xml.parsers.SAXParserFactory
;
import
org.xml.sax.InputSource
;
import
org.xml.sax.SAXException
;
import
eu.simstadt.nf4j.Job
;
import
eu.simstadt.nf4j.Connector
;
import
eu.simstadt.nf4j.FailedTransmissionException
;
import
eu.simstadt.nf4j.InvalidJobDescriptorException
;
import
eu.simstadt.nf4j.Job
;
import
eu.simstadt.nf4j.JobStatus
;
import
eu.simstadt.nf4j.Connector
;
/**
* NFConnector lets you communicate with your novaFACTORY (nF) server instance. It supports nF version 6.3.1.1.
*
For more
technical details about the NFConnector interface @see NFConnector.
* NFConnector lets you communicate with your novaFACTORY (nF) server instance. It supports nF version 6.3.1.1.
For more
* technical details about the NFConnector interface @see NFConnector.
*
* Please note, that this connector doesn't act asynchronously. This connector is safe, but will block your main
* application. You may rather want to use the asynchronous job implementations.
* application. You may rather want to use the asynchronous job implementations.
*
* @author Marcel Bruse
*
* @param <I> The import job descriptor implementation for this connector.
* @param <E> The export job descriptor implementation for this connector.
*/
public
class
HTTPConnection
implements
Connector
<
AsyncImportJob
,
AsyncExportJob
>
{
public
class
HTTPConnection
implements
Connector
<
AsyncImportJob
,
AsyncExportJob
>
{
/** Supported version of the novaFACTORY. */
public
static
final
String
NOVA_FACTORY_VERSION
=
"6.3.1.1"
;
/** The default context of the nF web application. It is part of any request URL directed at the nF server. */
public
static
final
String
DEFAULT_CONTEXT
=
"novaFACTORY"
;
/** The default port number of the nF web application. */
public
static
final
int
DEFAULT_PORT
=
80
;
/** The default protocol for requests. */
public
static
final
String
DEFAULT_PROTOCOL
=
"http"
;
/** The standard char set for requests. */
public
static
final
String
DEFAULT_CHARSET
=
"UTF-8"
;
/** The standard line separator required for file transmission via multipart/form-data. */
public
static
final
String
CRLF
=
"\r\n"
;
/** The name of nF's remote order servlet. */
public
static
final
String
REMOTE_ORDER_SERVLET
=
"RemoteOrder"
;
/** The name of nF's remote status servlet. */
public
static
final
String
REMOTE_STATUS_SERVLET
=
"RemoteStatus"
;
/** The name of nF's remote import servlet. */
public
static
final
String
REMOTE_IMPORT_SERVLET
=
"RemoteImport"
;
/** Default parser error message. */
public
static
final
String
XML_PARSER_ERROR
=
"Request failed due to an unknown XML parser error."
;
/** Default IO exception occurred message. */
public
static
final
String
IO_EXCEPTION_OCCURRED
=
public
static
final
String
IO_EXCEPTION_OCCURRED
=
"Request failed due to an IO exception. Check the host and port."
;
/** Default malformed URL message. */
public
static
final
String
MALFORMED_URL
=
"Request failed due to a malformed URL."
;
/** Default unknown error message. */
public
static
final
String
UNKNOWN_ERROR_OCCURRED
=
"An unknown error occurred."
;
/** The server or host name of the nF server. */
private
String
server
;
/** The port of the nF server. */
private
int
port
;
/** The protocol of the data connection. */
private
String
protocol
;
/** The context of the nF web application. It is part of any request URL directed at the nF server. */
private
String
context
;
/**
* Constructs your Connector instance.
*
...
...
@@ -107,7 +106,7 @@ public class HTTPConnection implements Connector<AsyncImportJob, AsyncExportJob>
public
HTTPConnection
(
String
server
)
{
this
(
server
,
DEFAULT_PORT
,
DEFAULT_CONTEXT
,
DEFAULT_PROTOCOL
);
}
/**
* Constructs your Connector instance.
*
...
...
@@ -126,9 +125,9 @@ public HTTPConnection(String server, int port, String context, String protocol)
* Callers of this NFConnector want to know the actual version of the novaFACTORY and the versions of its
* HTTP/FTP/WPS/etc. interfaces against which this interface has been implemented.
*
* The NovaFACTORY interfaces may change over time. Such changes force the SimStadt programmers to
*
implement
different versions of this NFConnector interface while keeping old implementations in order to
*
ensure backward
compatibility.
* The NovaFACTORY interfaces may change over time. Such changes force the SimStadt programmers to
implement
* different versions of this NFConnector interface while keeping old implementations in order to
ensure backward
* compatibility.
*
* @return The supported version of the novaFACTORY.
*/
...
...
@@ -136,7 +135,7 @@ public HTTPConnection(String server, int port, String context, String protocol)
public
String
supportsNFVersion
()
{
return
NOVA_FACTORY_VERSION
;
}
/**
* Returns the status of any existing nF export job.
*
...
...
@@ -162,7 +161,7 @@ public AsyncExportJob requestExportJob(int jobId) throws FailedTransmissionExcep
}
return
result
;
}
/**
* Returns the status of any existing nF import job.
*
...
...
@@ -190,12 +189,12 @@ public AsyncImportJob requestImportJob(int jobId) throws FailedTransmissionExcep
}
return
result
;
}
/**
* Downloads the result for a given nF export job and hands over the corresponding file handle.
*
* @param jobId The id of the export job for which the result should be loaded.
* @return A file handle to the result of the nF export job.
* @return A file handle to the result of the nF export job.
*/
@Override
public
File
requestExportJobResult
(
AsyncExportJob
job
)
throws
FailedTransmissionException
{
...
...
@@ -216,7 +215,7 @@ public File requestExportJobResult(AsyncExportJob job) throws FailedTransmission
}
return
result
;
}
/**
* Builds a simple parameter string for a HTTP GET request string.
*
...
...
@@ -227,10 +226,9 @@ public File requestExportJobResult(AsyncExportJob job) throws FailedTransmission
private
String
buildParameter
(
String
key
,
Object
value
)
{
return
key
+
"="
+
value
;
}
/**
* Builds a HTTP GET request URL out of the used protocol, nF server, port, context, servlet and existing
* parameters.
* Builds a HTTP GET request URL out of the used protocol, nF server, port, context, servlet and existing parameters.
*
* @param servlet One of the supported nF servlets RemoteOrder, RemoteStatus or RemoteImport.
* @param parameters List of parameters to be send to the servlet.
...
...
@@ -244,31 +242,31 @@ private URL buildURL(String servlet, List<String> parameters) throws MalformedUR
}
return
new
URL
(
url
);
}
/**
* Requests a response from the given URL. The response is expected to be returned as nF XML report.
*
* @param url The URL of the nF servlet with all its necessary parameters. Read the nF handbook for more
*
details
about the usage of nF servlets.
* @param url The URL of the nF servlet with all its necessary parameters. Read the nF handbook for more
details
*
about the usage of nF servlets.
* @return The response is expected to be a XML report, which will then be returned as a String.
* @throws IOException You will get some of this, if anything goes wrong with your data connection to your
*
nF
instance.
* @throws IOException You will get some of this, if anything goes wrong with your data connection to your
nF
*
instance.
*/
private
String
getResponse
(
URL
url
)
throws
UnsupportedEncodingException
,
IOException
{
HttpURLConnection
httpConnection
=
(
HttpURLConnection
)
url
.
openConnection
();
httpConnection
.
setRequestProperty
(
"Accept-Charset"
,
DEFAULT_CHARSET
);
return
getResponse
(
httpConnection
);
}
/**
* Requests a response from the given HTTP connection. The response is expected to be a XML document.
* Requests a response from the given HTTP connection. The response is expected to be a XML document.
*
* @param httpConnection The HTTP Connection to the nF servlet. Read the nF handbook for more details
*
about the usage
of the nF servlets.
* @param httpConnection The HTTP Connection to the nF servlet. Read the nF handbook for more details
about the usage
*
of the nF servlets.
* @return The response is expected to be a XML report, which will then be returned as a String.
* @throws UnsupportedEncodingException You will get some of this, if your connection uses wrong encodings.
* @throws IOException You will get some of this, if anything goes wrong with your data connection to your
*
nF
instance.
* @throws IOException You will get some of this, if anything goes wrong with your data connection to your
nF
*
instance.
*/
private
String
getResponse
(
HttpURLConnection
httpConnection
)
throws
UnsupportedEncodingException
,
IOException
{
String
xml
=
""
;
...
...
@@ -287,7 +285,7 @@ private String getResponse(HttpURLConnection httpConnection) throws UnsupportedE
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
xml
+=
line
;
}
}
}
response
.
close
();
}
else
{
...
...
@@ -295,22 +293,22 @@ private String getResponse(HttpURLConnection httpConnection) throws UnsupportedE
}
return
xml
;
}
/**
* If everything works as expected, then nF's servlets will respond with XML reports to your requests. The job
*
id and
status will be extracted from the response string. The id of the passed job instance will be updated.
*
The XML
reports have a certain structure. Read the nF manual for more information about the XML reports and
*
have a look at
the DTD of the XML reports.
* If everything works as expected, then nF's servlets will respond with XML reports to your requests. The job
id and
* status will be extracted from the response string. The id of the passed job instance will be updated.
The XML
* reports have a certain structure. Read the nF manual for more information about the XML reports and
have a look at
* the DTD of the XML reports.
*
* @param xml A XML string that is supposed to be a XML document.
* @param An empty job status object about to be filled with the actual result. It will be UNKOWN if there was
*
no XML
report in the response.
* @param An empty job status object about to be filled with the actual result. It will be UNKOWN if there was
no XML
*
report in the response.
* @throws ParserConfigurationException Something went wrong.
* @throws SAXException Some parse error.
* @throws IOException Some parse error.
*/
private
void
getJobFromResponse
(
Job
job
,
String
xml
)
throws
ParserConfigurationException
,
SAXException
,
IOException
,
FailedTransmissionException
{
throws
ParserConfigurationException
,
SAXException
,
IOException
,
FailedTransmissionException
{
SAXParserFactory
saxFactory
=
SAXParserFactory
.
newInstance
();
SAXParser
parser
=
saxFactory
.
newSAXParser
();
StringReader
reader
=
new
StringReader
(
xml
);
...
...
@@ -326,13 +324,13 @@ private void getJobFromResponse(Job job, String xml)
throw
new
FailedTransmissionException
(
handler
.
serviceException
);
}
}
/**
* Downloads a (zipped) CityGML file from the nF server. The file will be the result of an export job.
*
* @param url The URL of the remote order servlet that points at the CityGML file on the nF server.
* @return Returns a handle to the downloaded (zipped) CityGML file. Will be null if no file has been
*
downloaded (due
to errors).
*
* @param url The URL of the remote order servlet that points at the CityGML file on the nF server.
* @return Returns a handle to the downloaded (zipped) CityGML file. Will be null if no file has been
downloaded (due
*
to errors).
* @throws IOException Something went wrong with your data connection. Check your server and the port.
*/
private
File
downloadFile
(
URL
url
)
throws
IOException
{
...
...
@@ -341,26 +339,26 @@ private File downloadFile(URL url) throws IOException {
httpConnection
.
setRequestProperty
(
"Accept-Charset"
,
DEFAULT_CHARSET
);
if
(
httpConnection
.
getResponseCode
()
==
HttpURLConnection
.
HTTP_OK
)
{
String
filename
=
"result.gml"
;
String
disposition
=
httpConnection
.
getHeaderField
(
"Content-Disposition"
);
if
(
disposition
!=
null
)
{
int
index
=
disposition
.
indexOf
(
"filename="
);
if
(
index
>
-
1
)
{
filename
=
disposition
.
substring
(
index
+
9
,
disposition
.
length
()).
replaceAll
(
"\""
,
""
).
replaceAll
(
";"
,
""
);
}
}
InputStream
inputStream
=
httpConnection
.
getInputStream
();
FileOutputStream
outputStream
=
new
FileOutputStream
(
filename
);
int
bytesRead
=
-
1
;
byte
[]
buffer
=
new
byte
[
4096
]
;
while
((
bytesRead
=
inputStream
.
read
(
buffer
))
!=
-
1
)
{
out
putStream
.
write
(
buffer
,
0
,
bytesRead
);
}
outputStream
.
close
();
in
putStream
.
close
();
handle
=
new
File
(
filename
);
String
disposition
=
httpConnection
.
getHeaderField
(
"Content-Disposition"
);
if
(
disposition
!=
null
)
{
int
index
=
disposition
.
indexOf
(
"filename="
);
if
(
index
>
-
1
)
{
filename
=
disposition
.
substring
(
index
+
9
,
disposition
.
length
()).
replaceAll
(
"\""
,
""
).
replaceAll
(
";"
,
""
);
}
}
InputStream
inputStream
=
httpConnection
.
getInputStream
();
handle
=
Files
.
createTempDirectory
(
"nfDownload"
).
resolve
(
filename
).
toFile
(
);
FileOutputStream
outputStream
=
new
FileOutputStream
(
handle
)
;
int
bytesRead
=
-
1
;
byte
[]
buffer
=
new
byte
[
4096
];
while
((
bytesRead
=
in
putStream
.
read
(
buffer
))
!=
-
1
)
{
outputStream
.
write
(
buffer
,
0
,
bytesRead
);
}
out
putStream
.
close
();
inputStream
.
close
(
);
}
else
{
throw
new
IOException
();
}
...
...
@@ -372,10 +370,10 @@ private File downloadFile(URL url) throws IOException {
*
* @param file The XML file which describes the nF export job.
* @return Returns the status of the export job you just sent.
* @throws InvalidJobDescriptorException
* @throws InvalidJobDescriptorException
*/
@Override
public
void
sendAndUpdateExportJob
(
AsyncExportJob
job
)
public
void
sendAndUpdateExportJob
(
AsyncExportJob
job
)
throws
InvalidJobDescriptorException
,
FailedTransmissionException
{
JobFileBuilderImpl
jobFileBuilder
=
new
JobFileBuilderImpl
();
File
exportJobFile
=
jobFileBuilder
.
buildExportJobFile
(
job
.
getDescriptor
());
...
...
@@ -386,7 +384,7 @@ public void sendAndUpdateExportJob(AsyncExportJob job)
connection
.
setRequestProperty
(
"Connection"
,
"Keep-Alive"
);
connection
.
setRequestProperty
(
"Content-Type"
,
"application/x-www-form-urlencoded"
);
connection
.
setDoOutput
(
true
);
// Sends export job file
connection
.
setDoInput
(
true
);
// Expects XML response
connection
.
setDoInput
(
true
);
// Expects XML response
connection
.
connect
();
OutputStream
os
=
connection
.
getOutputStream
();
PrintWriter
writer
=
new
PrintWriter
(
new
OutputStreamWriter
(
os
,
DEFAULT_CHARSET
),
true
);
...
...
@@ -412,34 +410,30 @@ public void sendAndUpdateExportJob(AsyncExportJob job)
}
/**
* Sends an import job to nF. The given import job file has to be a zip file and has to obey the internal
*
structure
defined in the nF manuals. Short description:
* Sends an import job to nF. The given import job file has to be a zip file and has to obey the internal
structure
* defined in the nF manuals. Short description:
*
* Import jobs enable you to add, alter and delete CityGML top level objects (like buildings) in the nF.
*
Every import
job file has to contain a start file. Start files control the import process through their
*
file names and their
contents. The name of a start file has the following structure
* Import jobs enable you to add, alter and delete CityGML top level objects (like buildings) in the nF.
Every import
* job file has to contain a start file. Start files control the import process through their
file names and their
* contents. The name of a start file has the following structure
*
*
<Product>_<Tile>.start
* <Product>_<Tile>.start
*
* The start file should contain the level to which your manipulated CityGML should be imported. Your CityGML
*
file
and the ZIP archive has to be named after the following naming convention:
* The start file should contain the level to which your manipulated CityGML should be imported. Your CityGML
file
* and the ZIP archive has to be named after the following naming convention:
*
* <Product>_<Tile>_<Level>_<Operation>.gml
*
* Here operation can be ...
* - 'REP': Replaces whole existing buildings only,
* - 'REPUPD': Replaces whole existing buildings and adds new buildings,
* - 'UPD': Update, same as REP,
* - 'CHG': Change, same as REPUPD,
* - 'DEL': Deletes the geometry of a particular LOD,
* - 'DELALL': Deletes a whole building
* <Product>_<Tile>_<Level>_<Operation>.gml
*
* Here operation can be ... - 'REP': Replaces whole existing buildings only, - 'REPUPD': Replaces whole existing
* buildings and adds new buildings, - 'UPD': Update, same as REP, - 'CHG': Change, same as REPUPD, - 'DEL': Deletes
* the geometry of a particular LOD, - 'DELALL': Deletes a whole building
*
* @param file The nF import job as a prepared ZIP file. It has to contain the CityGML file and the start file.
* @return Returns the job status of your import job.
* @throws FailedTransmissionException
* @throws FailedTransmissionException
*/
@Override
public
void
sendAndUpdateImportJob
(
AsyncImportJob
job
)
public
void
sendAndUpdateImportJob
(
AsyncImportJob
job
)
throws
InvalidJobDescriptorException
,
FailedTransmissionException
{
if
(
job
.
getStatus
()
!=
JobStatus
.
LOCAL
)
{
throw
new
FailedTransmissionException
(
"Job cannot be sent twice!"
);
...
...
@@ -449,9 +443,9 @@ public void sendAndUpdateImportJob(AsyncImportJob job)
try
{
String
product
=
job
.
getDescriptor
().
getProduct
();
List
<
String
>
parameters
=
Arrays
.
asList
(
buildParameter
(
"request"
,
"imp"
),
// trigger import
buildParameter
(
"pdctKrz"
,
product
),
// the nF product to import to
buildParameter
(
"createjob"
,
"1"
));
// force nF to create an import job with a job number
buildParameter
(
"request"
,
"imp"
),
// trigger import
buildParameter
(
"pdctKrz"
,
product
),
// the nF product to import to
buildParameter
(
"createjob"
,
"1"
));
// force nF to create an import job with a job number
URL
url
=
buildURL
(
REMOTE_IMPORT_SERVLET
,
parameters
);
HttpURLConnection
connection
=
(
HttpURLConnection
)
url
.
openConnection
();
connection
.
setRequestMethod
(
"POST"
);
...
...
@@ -459,7 +453,7 @@ public void sendAndUpdateImportJob(AsyncImportJob job)
connection
.
setRequestProperty
(
"Accept"
,
"*/*"
);
connection
.
setRequestProperty
(
""
,
""
);
connection
.
setDoOutput
(
true
);
// Sends export job file
connection
.
setDoInput
(
true
);
// Expects XML response
connection
.
setDoInput
(
true
);
// Expects XML response
connection
.
connect
();
OutputStream
os
=
connection
.
getOutputStream
();
PrintWriter
writer
=
new
PrintWriter
(
new
OutputStreamWriter
(
os
,
DEFAULT_CHARSET
),
true
);
...
...
@@ -483,5 +477,5 @@ public void sendAndUpdateImportJob(AsyncImportJob job)
throw
new
FailedTransmissionException
(
ex
.
getMessage
());
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment