From 82952470c87f3f8bbb5eb5742f29adb6b2291e76 Mon Sep 17 00:00:00 2001 From: bruse <bruse@2c044af0-2e85-064f-a0c3-7471430cffcd> Date: Wed, 10 Dec 2014 16:50:00 +0000 Subject: [PATCH] Introduced some convenience methods for the Job class. --- src/eu/simstadt/nf4j/ExportJob.java | 57 ++++++----- .../nf4j/ExportJobDescriptorImpl.java | 74 ++------------- src/eu/simstadt/nf4j/ImportJob.java | 48 +++++----- src/eu/simstadt/nf4j/Job.java | 74 +++++++++++---- src/eu/simstadt/nf4j/JobFileBuilderImpl.java | 22 +++-- src/eu/simstadt/nf4j/JobStatus.java | 26 +++-- src/eu/simstadt/nf4j/Layer.java | 14 +++ src/eu/simstadt/nf4j/Main.java | 60 ++++++++---- src/eu/simstadt/nf4j/NFConnector.java | 21 ++--- src/eu/simstadt/nf4j/NFConnectorImpl.java | 50 +++++----- src/eu/simstadt/nf4j/Unit.java | 94 +++++++++++++++++++ 11 files changed, 324 insertions(+), 216 deletions(-) create mode 100644 src/eu/simstadt/nf4j/Unit.java diff --git a/src/eu/simstadt/nf4j/ExportJob.java b/src/eu/simstadt/nf4j/ExportJob.java index 4275c62..018d2f7 100644 --- a/src/eu/simstadt/nf4j/ExportJob.java +++ b/src/eu/simstadt/nf4j/ExportJob.java @@ -1,5 +1,6 @@ package eu.simstadt.nf4j; +import java.io.File; import java.util.Objects; /** @@ -7,37 +8,33 @@ * * @author Marcel Bruse */ -public class ExportJob extends Job { - - /** - * Initializes a new export job instance with unknown state. This is a convenient method. - * - * @return Returns a new export job instance with unknown state. - */ - public static ExportJob getNewInstance() { - return new ExportJob(JobStatus.UNKOWN); - } +public class ExportJob extends Job<ExportJobDescriptorImpl> { /** - * Initializes a new export job instance with unknown state and connector instance. This is a - * convenient method. + * 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 The nF connector which answers status requests for this job. - * @return Returns a new export job instance with unknown state. + * @param connector The job will use this connector to synchronize itself with the nF. + * @param descriptor The description of this job. */ - public static ExportJob getNewInstance(NFConnector<?, ?> nFConnector) { - ExportJob result = getNewInstance(); - result.setNFConnector(nFConnector); - return result; + public ExportJob(ExportJobDescriptorImpl descriptor, NFConnector connector) { + super(descriptor, connector); + status = JobStatus.LOCAL; } - + /** - * This constructor forces the job to have a defined state. + * 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. * - * @param status + * @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 ExportJob(JobStatus status) { - super(status); + public ExportJob(int id, NFConnector connector) { + super(id, connector); + status = JobStatus.SENT; } /** @@ -48,7 +45,7 @@ public ExportJob(JobStatus status) { */ public void updateStatus() throws FailedTransmissionException { if (Objects.nonNull(getNFConnector())) { - Job job = getNFConnector().requestExportJob(getJobId()); + Job<ExportJobDescriptorImpl> job = getNFConnector().requestExportJob(getId()); setStatus(job.getStatus()); } else { throw new FailedTransmissionException(); @@ -83,5 +80,17 @@ public void setStatusForCode(int statusCode) { public boolean isFinished() { return Objects.nonNull(getStatus()) && getStatus().equals(JobStatus.FINISHED); } + + @Override + public void send() throws InvalidJobDescriptorException, FailedTransmissionException { + connector.sendAndUpdateExportJob(this); + } + + public File requestExportJobResult() throws FailedTransmissionException { + if (!isFinished()) { + throw new FailedTransmissionException("Job is not finished yet!"); + } + return connector.requestExportJobResult(id); + } } diff --git a/src/eu/simstadt/nf4j/ExportJobDescriptorImpl.java b/src/eu/simstadt/nf4j/ExportJobDescriptorImpl.java index c80f635..cee5bee 100644 --- a/src/eu/simstadt/nf4j/ExportJobDescriptorImpl.java +++ b/src/eu/simstadt/nf4j/ExportJobDescriptorImpl.java @@ -42,14 +42,6 @@ public class ExportJobDescriptorImpl implements ExportJobDescriptor { private static final String DEFAULT_MERGE_MAP_SHEETS = "off"; private static final String DEFAULT_TILE1ASGN = "false"; - - private static final String DEFAULT_EXTERIOR = "0"; - - private static final String DEFAULT_FRAME = "0"; - - private static final String DEFAULT_SELECT_MAP_SHEETS = "0"; - - private static final String DEFAULT_SUBDIVISION = "4"; private static final String DEFAULT_SRS = "31467"; @@ -109,20 +101,8 @@ public class ExportJobDescriptorImpl implements ExportJobDescriptor { /** The tile1asgn attribute of the extent tag. */ private String tile1asgn; - /** The exterior attribute of the unit tag. */ - private String exterior; - - /** The frame attribute of the unit tag. */ - private String frame; - - /** The select mapsheet attribute of the unit tag. */ - private String selectMapsheets; - - /** The subdivision attribute of the unit tag. */ - private String subdivision; - /** The unit tag of the extent. */ - private String unit; + private ArrayList<Unit> unitList = new ArrayList<>(); /** The polygon of the selected region which should be exported. */ ArrayList<Coord> regionPolygon = new ArrayList<>(); @@ -263,20 +243,12 @@ public void setMergeMapsheets(String mergeMapsheets) { this.mergeMapsheets = mergeMapsheets; } - public String getUnit() { - return unit; + public ArrayList<Unit> getUnitList() { + return unitList; } - public void setUnit(String unit) { - this.unit = unit; - } - - public String getExterior() { - return exterior; - } - - public void setExterior(String exterior) { - this.exterior = exterior; + public void addUnit(Unit unit) { + unitList.add(unit); } public String getTile1asgn() { @@ -286,30 +258,6 @@ public String getTile1asgn() { public void setTile1asgn(String tile1asgn) { this.tile1asgn = tile1asgn; } - - public String getFrame() { - return frame; - } - - public void setFrame(String frame) { - this.frame = frame; - } - - public String getSelectMapsheets() { - return selectMapsheets; - } - - public void setSelectMapsheets(String selectMapsheets) { - this.selectMapsheets = selectMapsheets; - } - - public String getSubdivision() { - return subdivision; - } - - public void setSubdivision(String subdivision) { - this.subdivision = subdivision; - } public String getResolution() { return resolution; @@ -443,13 +391,7 @@ public ArrayList<Coord> getRegionPolygon() { */ @Override public boolean isValid() { - if ((regionPolygon.isEmpty() - && (unit.isEmpty() - || exterior.isEmpty() - || frame.isEmpty() - || selectMapsheets.isEmpty() - || subdivision.isEmpty() - )) + if ((regionPolygon.isEmpty() && (unitList.isEmpty())) || layerList.isEmpty() || initiator.isEmpty() || account.isEmpty() @@ -486,11 +428,7 @@ public static ExportJobDescriptorImpl getDefaultDescriptor() { descriptor.setSingle(DEFAULT_SINGLE); descriptor.setSrs(DEFAULT_SRS); descriptor.setMergeMapsheets(DEFAULT_MERGE_MAP_SHEETS); - descriptor.setExterior(DEFAULT_EXTERIOR); descriptor.setTile1asgn(DEFAULT_TILE1ASGN); - descriptor.setFrame(DEFAULT_FRAME); - descriptor.setSelectMapsheets(DEFAULT_SELECT_MAP_SHEETS); - descriptor.setSubdivision(DEFAULT_SUBDIVISION); descriptor.setResolution(DEFAULT_RESOLUTION); descriptor.setScale(DEFAULT_SCALE); descriptor.setFormat(DEFAULT_FORMAT); diff --git a/src/eu/simstadt/nf4j/ImportJob.java b/src/eu/simstadt/nf4j/ImportJob.java index c216034..696706d 100644 --- a/src/eu/simstadt/nf4j/ImportJob.java +++ b/src/eu/simstadt/nf4j/ImportJob.java @@ -7,37 +7,33 @@ * * @author Marcel Bruse */ -public class ImportJob extends Job { +public class ImportJob extends Job<ImportJobDescriptorImpl> { /** - * Initializes a new import job instance with unknown state. This is a convenient method. + * 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. * - * @return Returns a new import job instance with unknown state. + * @param connector The job will use this connector to synchronize itself with the nF. + * @param descriptor The description of this job. */ - public static ImportJob getNewInstance() { - return new ImportJob(JobStatus.UNKOWN); + public ImportJob(ImportJobDescriptorImpl descriptor, NFConnector connector) { + super(descriptor, connector); + status = JobStatus.LOCAL; } /** - * Initializes a new import job instance with unknown state and connector instance. This is a - * convenient method. + * 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. * - * @param The nF connector which answers status requests for this job. - * @return Returns a new import job instance with unknown state. + * @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 static ImportJob getNewInstance(NFConnector<?, ?> nFConnector) { - ImportJob result = getNewInstance(); - result.setNFConnector(nFConnector); - return result; - } - - /** - * This constructor forces the job to have a defined state. - * - * @param status - */ - public ImportJob(JobStatus status) { - super(status); + public ImportJob(int id, NFConnector connector) { + super(id, connector); + status = JobStatus.SENT; } /** @@ -48,7 +44,7 @@ public ImportJob(JobStatus status) { */ public void updateStatus() throws FailedTransmissionException { if (Objects.nonNull(getNFConnector())) { - Job job = getNFConnector().requestImportJob(getJobId()); + Job<ImportJobDescriptorImpl> job = getNFConnector().requestImportJob(getId()); setStatus(job.getStatus()); } else { throw new FailedTransmissionException(); @@ -92,5 +88,11 @@ public void setStatusForCode(int statusCode) { setStatus(JobStatus.UNKOWN); } } + + @Override + public void send() throws InvalidJobDescriptorException, + FailedTransmissionException { + connector.sendAndUpdateImportJob(this); + } } diff --git a/src/eu/simstadt/nf4j/Job.java b/src/eu/simstadt/nf4j/Job.java index 8138def..72c6213 100644 --- a/src/eu/simstadt/nf4j/Job.java +++ b/src/eu/simstadt/nf4j/Job.java @@ -1,30 +1,45 @@ package eu.simstadt.nf4j; -import java.util.Objects; - /** * This job class bundles the three attributes of every nF job: Id, status and last job related nF (error) message. * * @author Marcel Bruse */ -public abstract class Job { +public abstract class Job<D extends JobDescriptor> { /** The status of the job. There are different states for export and import jobs. */ - private JobStatus status; + protected JobStatus status; + + /** Every job should have a (valid) job descriptor. */ + protected D descriptor; /** The id of the job. */ - private int jobId; + protected int id; /** The connection to the nF. */ - private NFConnector<?, ?> nFConnector; + protected NFConnector connector; /** - * This constructor forces the job to have a defined state. + * This constructor forces the job to have a description and a connector instance. * - * @param status The initial status of this job. + * @param connector The job will use this connector to synchronize itself with the nF. + * @param descriptor The description of this job. */ - public Job(JobStatus status) { - this.status = status; + public Job(D descriptor, NFConnector connector) { + this.descriptor = descriptor; + this.connector = connector; + } + + /** + * This constructor forces the job to have a id and a connector instance. + * + * @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 Job(int id, NFConnector connector) { + this.id = id; + this.connector = connector; } /** @@ -45,11 +60,18 @@ protected void setStatus(JobStatus status) { this.status = status; } + /** + * @return Returns the description of this job. + */ + public D getDescriptor() { + return descriptor; + } + /** * @return Returns the id of this job. */ - public int getJobId() { - return jobId; + public int getId() { + return id; } /** @@ -57,15 +79,15 @@ public int getJobId() { * * @param jobId The job id about to be set. */ - public void setJobId(int jobId) { - this.jobId = jobId; + public void setId(int jobId) { + this.id = jobId; } /** * @return Returns the nF connector of this job. */ - public NFConnector<?, ?> getNFConnector() { - return nFConnector; + public NFConnector getNFConnector() { + return connector; } /** @@ -73,13 +95,25 @@ public void setJobId(int jobId) { * * @param nFConnector The connector of this job. */ - public void setNFConnector(NFConnector<?, ?> nFConnector) { - this.nFConnector = nFConnector; + public void setNFConnector(NFConnector nFConnector) { + this.connector = nFConnector; } /** - * Connects to the nF and refreshes the status of this job. If there is no nF connector set, - * this operation will throw a FailedTransmissionException. + * This method reads the job description, builds a job file from it and uses the connector to send the + * job file to nF. You may want to implement the file building and file sending parts in the + * connector in order to reuse them here. + * + * This method is a object oriented convenience method for NFConnector.sendXXXJobFile(). It is sensible + * to have this convenience method, because it offers the API user centralized controls over the jobs + * status chain without switching between job instances and connector instances. In the end, the user is + * not interested in the connection to the nF, but in the job itself. + */ + public abstract void send() throws InvalidJobDescriptorException, FailedTransmissionException; + + /** + * Connects to the nF and refreshes the status of this job. If there is no nF connector set, or the job id + * is unkown by the nF, then this operation will throw a FailedTransmissionException. * * @throws FailedTransmissionException If the connection to the nF is broken you will get some of this. */ diff --git a/src/eu/simstadt/nf4j/JobFileBuilderImpl.java b/src/eu/simstadt/nf4j/JobFileBuilderImpl.java index 7a40117..c298752 100644 --- a/src/eu/simstadt/nf4j/JobFileBuilderImpl.java +++ b/src/eu/simstadt/nf4j/JobFileBuilderImpl.java @@ -117,17 +117,19 @@ public File buildExportJobFile(ExportJobDescriptorImpl jobDescriptor) throws Inv extent.setAttribute("merge_mapsheets", jobDescriptor.getMergeMapsheets()); root.appendChild(extent); - if (!jobDescriptor.getUnit().isEmpty()) { + if (!jobDescriptor.getUnitList().isEmpty()) { extent.setAttribute("tile1asgn", jobDescriptor.getTile1asgn()); - Element unit = doc.createElement("unit"); - unit.setAttribute("exterior", jobDescriptor.getExterior()); - unit.setAttribute("frame", jobDescriptor.getFrame()); - unit.setAttribute("select_mapsheets", jobDescriptor.getSelectMapsheets()); - unit.setAttribute("subdivision", jobDescriptor.getSubdivision()); - unit.appendChild(doc.createTextNode(jobDescriptor.getUnit())); - extent.appendChild(unit); + for (Unit unit : jobDescriptor.getUnitList()) { + Element unitElement = doc.createElement("unit"); + unitElement.setAttribute("exterior", unit.getExterior()); + unitElement.setAttribute("frame", unit.getFrame()); + unitElement.setAttribute("select_mapsheets", unit.getSelectMapsheets()); + unitElement.setAttribute("subdivision", unit.getSubdivision()); + unitElement.appendChild(doc.createTextNode(unit.getValue())); + extent.appendChild(unitElement); + } } else { - Element polygon = appendRegionPolygon(doc, jobDescriptor.regionPolygon); + Element polygon = createRegionPolygonElement(doc, jobDescriptor.regionPolygon); extent.appendChild(polygon); } @@ -276,7 +278,7 @@ public static ProjCoordinate transformCoordinate(ProjCoordinate wgs84Position, * @param regionPolygon The polygon of the region which has been selected to be exported. * @return The w3c.dom.Element of the XML export job which describes the region polygon. */ - private static Element appendRegionPolygon(Document doc, List<Coord> regionPolygon) { + private static Element createRegionPolygonElement(Document doc, List<Coord> regionPolygon) { Element polygon = doc.createElement("polygon"); polygon.setAttribute("srs", "31467"); CRSFactory f = new CRSFactory(); diff --git a/src/eu/simstadt/nf4j/JobStatus.java b/src/eu/simstadt/nf4j/JobStatus.java index 49941cd..3725da3 100644 --- a/src/eu/simstadt/nf4j/JobStatus.java +++ b/src/eu/simstadt/nf4j/JobStatus.java @@ -6,11 +6,13 @@ * @author Marcel Bruse */ public enum JobStatus { - UNKOWN(0), PENDING(1), RUNNING(2), FAILED(3), FINISHED(4), READY_TO_RUN(5), ERROR(6), WARNING(7), APPROVE(8), - REJECT(9), APPROVE_RUNNING(10), REJECT_RUNNING(11), APPROVE_REJECT_ERROR(12), APPROVE_REJECT_OK(13), - IMPORTED_WARNING(14); + UNKOWN(0), LOCAL(1), SENT(2), PENDING(3), RUNNING(4), FAILED(5), FINISHED(6), READY_TO_RUN(7), ERROR(8), + WARNING(9), APPROVE(10), REJECT(11), APPROVE_RUNNING(12), REJECT_RUNNING(13), APPROVE_REJECT_ERROR(14), + APPROVE_REJECT_OK(15), IMPORTED_WARNING(16); - public static final String UNKNOWN_STATUS_MESSAGE = "The state of the job is unknown."; + public static final String UNKNOWN_MESSAGE = "The state of the job is unknown."; + public static final String LOCAL_MESSAGE = "The job is known locally only. It has not been sent yet."; + public static final String SENT_MESSAGE = "The job has been sent, is enqueued at the nF and has a job id."; public static final String PENDING_MESSAGE = "Job is pending."; public static final String RUNNING_MESSAGE = "Job is running."; public static final String FAILED_MESSAGE = "Job failed."; @@ -24,16 +26,20 @@ public enum JobStatus { private JobStatus(int internalCode) { switch (internalCode) { case 0: - message = UNKNOWN_STATUS_MESSAGE; break; + message = UNKNOWN_MESSAGE; break; case 1: - case 5: - message = PENDING_MESSAGE; break; + message = LOCAL_MESSAGE; break; case 2: - message = RUNNING_MESSAGE; break; + message = SENT_MESSAGE; break; case 3: - case 6: - message = FAILED_MESSAGE; break; + case 7: + message = PENDING_MESSAGE; break; case 4: + message = RUNNING_MESSAGE; break; + case 5: + case 8: + message = FAILED_MESSAGE; break; + case 6: message = FINISHED_MESSAGE; break; default: message = ""; diff --git a/src/eu/simstadt/nf4j/Layer.java b/src/eu/simstadt/nf4j/Layer.java index 51af5d5..b940cb6 100644 --- a/src/eu/simstadt/nf4j/Layer.java +++ b/src/eu/simstadt/nf4j/Layer.java @@ -7,6 +7,12 @@ * @author Marcel Bruse */ public class Layer { + + private static final String DEFAULT_NAME = "GML"; + + private static final String DEFAULT_PRODUCT = "WU3"; + + private static final String DEFAULT_STYLE = "#000000"; /** The name of the layer. */ private String name; @@ -83,4 +89,12 @@ public void setStyle(String style) { this.style = style; } + public static Layer getDefaultLayer() { + Layer layer = new Layer(); + layer.setName(DEFAULT_NAME); + layer.setProduct(DEFAULT_PRODUCT); + layer.setStyle(DEFAULT_STYLE); + return layer; + } + } diff --git a/src/eu/simstadt/nf4j/Main.java b/src/eu/simstadt/nf4j/Main.java index c4ec662..29ebaa2 100644 --- a/src/eu/simstadt/nf4j/Main.java +++ b/src/eu/simstadt/nf4j/Main.java @@ -1,27 +1,47 @@ package eu.simstadt.nf4j; -import java.io.File; +import java.util.Arrays; +import java.util.function.Consumer; public class Main { - - public static void main(String[] args) { -//// ImportJobDescriptorImpl desc = ImportJobDescriptorImpl.getDefaultDescriptor(); -//// desc.setProduct("WUDEV"); -//// desc.setLeaf("820"); -//// desc.setCityGMLFile(new File("WUDEV_820_GML.gml")); -//// desc.addADESchemaFile(new File("energy.xsd")); -//// System.out.println(desc.getCityGMLFile().canRead()); -// -// NFConnectorImpl connector = new NFConnectorImpl("193.196.136.164"); -// -// try { -//// ImportJob job = connector.sendImportJobFile(desc); -// ImportJob job = connector.requestImportJob(301); -// job.updateStatus(); -// System.out.println(job.getJobId() + ": " + job.getStatus()); -// } catch (FailedTransmissionException ex) { -// ex.printStackTrace(); -// } + + public static void main(String[] args) { + + ExportJobDescriptorImpl jobDescriptor = ExportJobDescriptorImpl.getDefaultDescriptor(); + jobDescriptor.setProduct("WU3"); + + Arrays.asList("820", "821", "822", "823", "824").forEach(new Consumer<String>() { + @Override + public void accept(String unitLabel) { + Unit unit = Unit.getDefaultUnit(); + unit.setValue(unitLabel); + jobDescriptor.addUnit(unit); + } + }); + + Layer layer = Layer.getDefaultLayer(); + layer.setProduct("WU3"); + layer.setName("GML"); + + jobDescriptor.addLayer(layer); + + ExportJob job = new ExportJob(jobDescriptor, new NFConnectorImpl("193.196.136.164")); + + try { + job.send(); + int i = 1; + while(!job.isFinished()) { + System.out.println(i++); + Thread.sleep(5000l); + job.updateStatus(); + System.out.println(job.getStatus()); + } + job.requestExportJobResult(); + } catch (FailedTransmissionException | InvalidJobDescriptorException ex) { + ex.printStackTrace(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } } } \ No newline at end of file diff --git a/src/eu/simstadt/nf4j/NFConnector.java b/src/eu/simstadt/nf4j/NFConnector.java index bb9ccd6..04d93d8 100644 --- a/src/eu/simstadt/nf4j/NFConnector.java +++ b/src/eu/simstadt/nf4j/NFConnector.java @@ -6,11 +6,8 @@ * NFConnector lets you communicate with your novaFACTORY (nF) server instance. * * @author Marcel Bruse - * - * @param <I> The import job descriptor implementation for this connector. - * @param <E> The export job descriptor implementation for this connector. */ -public interface NFConnector<I extends ImportJobDescriptor, E extends ExportJobDescriptor> { +public interface NFConnector { /** * Callers of this NFConnector want to know the actual version of the novaFACTORY and the versions of its @@ -27,12 +24,13 @@ /** * Sends an export job to nF. The job has to be passed to the nF in an appropriate XML job file. * The DTD of the XML format can be obtained from the nF installation or documentation. - * The contents of the XML job file are detailed in a job descriptor. - * - * @param jobDescriptor The nF export job description. - * @return The status of the job. Could be pending or failed. + * The contents of the XML job file are detailed in the job's descriptor instance. This method is supposed to + * update the status of the job and the job id. + * + * @param job The nF export job with description. If the job description is invalid, you will receive an + * InvalidJobDescriptorException. */ - public ExportJob sendExportJobFile(E exportJobDescriptor) + public void sendAndUpdateExportJob(ExportJob job) throws InvalidJobDescriptorException, FailedTransmissionException; /** @@ -59,10 +57,9 @@ public ExportJob sendExportJobFile(E exportJobDescriptor) * - '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 id of your import job or -1 if something went wrong. + * @param job The nF import job to be sent. It has to contain a valid description. */ - public ImportJob sendImportJobFile(I importJobDescriptor) + public void sendAndUpdateImportJob(ImportJob job) throws InvalidJobDescriptorException, FailedTransmissionException; /** diff --git a/src/eu/simstadt/nf4j/NFConnectorImpl.java b/src/eu/simstadt/nf4j/NFConnectorImpl.java index 275a04e..fc01968 100644 --- a/src/eu/simstadt/nf4j/NFConnectorImpl.java +++ b/src/eu/simstadt/nf4j/NFConnectorImpl.java @@ -35,7 +35,7 @@ * @param <I> The import job descriptor implementation for this connector. * @param <E> The export job descriptor implementation for this connector. */ -public class NFConnectorImpl implements NFConnector<ImportJobDescriptorImpl, ExportJobDescriptorImpl> { +public class NFConnectorImpl implements NFConnector { /** Supported version of the novaFACTORY. */ public static final String NOVA_FACTORY_VERSION = "6.3.1.1"; @@ -136,7 +136,7 @@ public String supportsNFVersion() { */ @Override public ExportJob requestExportJob(int jobId) throws FailedTransmissionException { - ExportJob result = ExportJob.getNewInstance(this); + ExportJob result = new ExportJob(jobId, this); try { List<String> parameters = Arrays.asList(buildParameter("jobid", jobId)); getJobFromResponse(result, getResponse(buildURL(REMOTE_STATUS_SERVLET, parameters))); @@ -162,7 +162,7 @@ public ExportJob requestExportJob(int jobId) throws FailedTransmissionException */ @Override public ImportJob requestImportJob(int jobId) throws FailedTransmissionException { - ImportJob result = ImportJob.getNewInstance(this); + ImportJob result = new ImportJob(jobId, this); try { List<String> parameters = Arrays.asList( buildParameter("jobid", jobId), @@ -295,10 +295,8 @@ private String getResponse(HttpURLConnection httpConnection) throws UnsupportedE * @throws SAXException Some parse error. * @throws IOException Some parse error. */ - private void getJobFromResponse(Job job, String xml) + private void getJobFromResponse(Job<?> job, String xml) throws ParserConfigurationException, SAXException, IOException { - JobStatus status = JobStatus.UNKOWN; - job.setStatus(status); SAXParserFactory saxFactory = SAXParserFactory.newInstance(); SAXParser parser = saxFactory.newSAXParser(); StringReader reader = new StringReader(xml); @@ -308,10 +306,10 @@ private void getJobFromResponse(Job job, String xml) job.setStatusForCode(handler.statusId); } if (Objects.nonNull(handler.serviceException)) { - status.setMessage(handler.serviceException); + job.getStatus().setMessage(handler.serviceException); } if (Objects.nonNull(handler.jobId)) { - job.setJobId(handler.jobId); + job.setId(handler.jobId); } } @@ -363,11 +361,10 @@ private File downloadFile(URL url) throws IOException { * @throws InvalidJobDescriptorException */ @Override - public ExportJob sendExportJobFile(ExportJobDescriptorImpl jobDescriptor) + public void sendAndUpdateExportJob(ExportJob job) throws InvalidJobDescriptorException, FailedTransmissionException { - ExportJob result = ExportJob.getNewInstance(); JobFileBuilderImpl jobFileBuilder = new JobFileBuilderImpl(); - File exportJobFile = jobFileBuilder.buildExportJobFile(jobDescriptor); + File exportJobFile = jobFileBuilder.buildExportJobFile(job.getDescriptor()); try { URL url = buildURL(REMOTE_ORDER_SERVLET, null); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -382,23 +379,20 @@ public ExportJob sendExportJobFile(ExportJobDescriptorImpl jobDescriptor) Files.copy(exportJobFile.toPath(), os); os.flush(); writer.append(CRLF).flush(); - getJobFromResponse(result, getResponse(connection)); - // At this line, result will be UNKNOWN, although the job has been enqueued. A separate status request - // will be sent in order to query for the actual state of the job. - if (result.getJobId() > 0) { - result = requestExportJob(result.getJobId()); - } + getJobFromResponse(job, getResponse(connection)); + // At this line, the job status will be unknown, although the job has been enqueued by the nF. + // A separate status request has to be sent in order to get the actual state of the job. + job.updateStatus(); } catch (MalformedURLException ex) { - result.getStatus().setMessage(MALFORMED_URL); + job.getStatus().setMessage(MALFORMED_URL); throw new FailedTransmissionException(ex.getMessage()); } catch (IOException ex) { - result.getStatus().setMessage(IO_EXCEPTION_OCCURRED); + job.getStatus().setMessage(IO_EXCEPTION_OCCURRED); throw new FailedTransmissionException(ex.getMessage()); } catch (ParserConfigurationException | SAXException ex) { - result.getStatus().setMessage(XML_PARSER_ERROR); + job.getStatus().setMessage(XML_PARSER_ERROR); throw new FailedTransmissionException(ex.getMessage()); } - return result; } /** @@ -429,11 +423,10 @@ public ExportJob sendExportJobFile(ExportJobDescriptorImpl jobDescriptor) * @throws FailedTransmissionException */ @Override - public ImportJob sendImportJobFile(ImportJobDescriptorImpl jobDescriptor) + public void sendAndUpdateImportJob(ImportJob job) throws InvalidJobDescriptorException, FailedTransmissionException { - ImportJob result = ImportJob.getNewInstance(); JobFileBuilderImpl jobFileBuilder = new JobFileBuilderImpl(); - File importJobFile = jobFileBuilder.buildImportJobFile(jobDescriptor); + File importJobFile = jobFileBuilder.buildImportJobFile(job.getDescriptor()); try { List<String> parameters = Arrays.asList( buildParameter("request", "imp"), // trigger import @@ -453,18 +446,17 @@ public ImportJob sendImportJobFile(ImportJobDescriptorImpl jobDescriptor) Files.copy(importJobFile.toPath(), os); os.flush(); writer.append(CRLF).flush(); - getJobFromResponse(result, getResponse(connection)); + getJobFromResponse(job, getResponse(connection)); } catch (MalformedURLException ex) { - result.getStatus().setMessage(MALFORMED_URL); + job.getStatus().setMessage(MALFORMED_URL); throw new FailedTransmissionException(ex.getMessage()); } catch (IOException ex) { - result.getStatus().setMessage(IO_EXCEPTION_OCCURRED); + job.getStatus().setMessage(IO_EXCEPTION_OCCURRED); throw new FailedTransmissionException(ex.getMessage()); } catch (SAXException | ParserConfigurationException ex) { - result.getStatus().setMessage(XML_PARSER_ERROR); + job.getStatus().setMessage(XML_PARSER_ERROR); throw new FailedTransmissionException(ex.getMessage()); } - return result; } } \ No newline at end of file diff --git a/src/eu/simstadt/nf4j/Unit.java b/src/eu/simstadt/nf4j/Unit.java new file mode 100644 index 0000000..19d554b --- /dev/null +++ b/src/eu/simstadt/nf4j/Unit.java @@ -0,0 +1,94 @@ +package eu.simstadt.nf4j; + +/** + * Units (Blattschnitte) divide regions into sections. For instance, the city of Stuttgart could have the units + * "Stg-Mitte", "Stg-West", "Bad Cannstatt", "Heslach", etc. + * + * @author Marcel Bruse + * + */ +public class Unit { + + private static final String DEFAULT_EXTERIOR = "0"; + + private static final String DEFAULT_FRAME = "0"; + + private static final String DEFAULT_SELECT_MAP_SHEETS = "0"; + + private static final String DEFAULT_SUBDIVISION = "4"; + + /** The exterior attribute of the unit tag. */ + private String exterior; + + /** The frame attribute of the unit tag. */ + private String frame; + + /** The select mapsheet attribute of the unit tag. */ + private String selectMapsheets; + + /** The subdivision attribute of the unit tag. */ + private String subdivision; + + /** The actual value of the unit tag. */ + private String value; + + public String getExterior() { + return exterior; + } + + public void setExterior(String exterior) { + this.exterior = exterior; + } + + public String getFrame() { + return frame; + } + + public void setFrame(String frame) { + this.frame = frame; + } + + public String getSelectMapsheets() { + return selectMapsheets; + } + + public void setSelectMapsheets(String selectMapsheets) { + this.selectMapsheets = selectMapsheets; + } + + public String getSubdivision() { + return subdivision; + } + + public void setSubdivision(String subdivision) { + this.subdivision = subdivision; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * @return Returns true, if the unit is valid. + */ + public boolean isValid() { + return !(exterior.isEmpty() + || frame.isEmpty() + || selectMapsheets.isEmpty() + || subdivision.isEmpty()); + } + + public static Unit getDefaultUnit() { + Unit unit = new Unit(); + unit.setExterior(DEFAULT_EXTERIOR); + unit.setFrame(DEFAULT_FRAME); + unit.setSelectMapsheets(DEFAULT_SELECT_MAP_SHEETS); + unit.setSubdivision(DEFAULT_SUBDIVISION); + return unit; + } + +} -- GitLab