svn-document-layout / trunk / org.gvsig.app.document.layout2.app / org.gvsig.app.document.layout2.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / report / LayoutReportActionImpl.java @ 1594
History | View | Annotate | Download (18.5 KB)
1 |
package org.gvsig.app.project.documents.layout.report; |
---|---|
2 |
|
3 |
import java.awt.Dimension; |
4 |
import java.awt.event.ActionEvent; |
5 |
import java.awt.geom.Point2D; |
6 |
import java.io.File; |
7 |
import java.io.IOException; |
8 |
import java.io.InputStream; |
9 |
import java.util.ArrayList; |
10 |
import java.util.List; |
11 |
import javax.json.Json; |
12 |
import javax.json.JsonObject; |
13 |
import javax.swing.JComponent; |
14 |
import org.apache.commons.io.IOUtils; |
15 |
import org.apache.commons.lang3.StringUtils; |
16 |
import org.gvsig.andami.ui.mdiManager.IWindow; |
17 |
import org.gvsig.app.ApplicationLocator; |
18 |
import org.gvsig.app.ApplicationManager; |
19 |
import org.gvsig.app.project.documents.Document; |
20 |
import org.gvsig.app.project.documents.layout.LayoutContext; |
21 |
import org.gvsig.app.project.documents.layout.fframes.FFrameView; |
22 |
import org.gvsig.app.project.documents.layout.fframes.IFFrame; |
23 |
import org.gvsig.app.project.documents.layout.gui.LayoutPanel; |
24 |
import static org.gvsig.app.project.documents.layout.report.LayoutReportActionFactory.LAYOUT_REPORT_ACTION_NAME; |
25 |
import org.gvsig.app.project.documents.view.ViewDocument; |
26 |
import org.gvsig.app.project.documents.view.gui.IView; |
27 |
import org.gvsig.desktopopen.DesktopOpen; |
28 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator; |
29 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
30 |
import org.gvsig.expressionevaluator.ExpressionUtils; |
31 |
import org.gvsig.expressionevaluator.MutableSymbolTable; |
32 |
import org.gvsig.fmap.dal.DALLocator; |
33 |
import org.gvsig.fmap.dal.exception.DataException; |
34 |
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable; |
35 |
import org.gvsig.fmap.dal.feature.Feature; |
36 |
import org.gvsig.fmap.dal.feature.FeatureQuery; |
37 |
import org.gvsig.fmap.dal.feature.FeatureSelection; |
38 |
import org.gvsig.fmap.dal.feature.FeatureSet; |
39 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
40 |
import org.gvsig.fmap.dal.swing.DALSwingLocator; |
41 |
import org.gvsig.fmap.dal.swing.DataSwingManager; |
42 |
import org.gvsig.fmap.dal.swing.report.AbstractReportAction; |
43 |
import org.gvsig.fmap.dal.swing.report.ReportActionFactory; |
44 |
import org.gvsig.fmap.geom.Geometry; |
45 |
import org.gvsig.fmap.geom.GeometryLocator; |
46 |
import org.gvsig.fmap.geom.exception.CreateEnvelopeException; |
47 |
import org.gvsig.fmap.geom.primitive.Envelope; |
48 |
import org.gvsig.fmap.mapcontext.MapContext; |
49 |
import org.gvsig.fmap.mapcontext.ViewPort; |
50 |
import org.gvsig.fmap.mapcontext.layers.FLayer; |
51 |
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect; |
52 |
import org.gvsig.pdf.lib.api.PDFDocument; |
53 |
import org.gvsig.pdf.lib.api.PDFLocator; |
54 |
import org.gvsig.pdf.lib.api.PDFManager; |
55 |
import org.gvsig.pdf.swing.api.PDFSwingLocator; |
56 |
import org.gvsig.pdf.swing.api.PDFSwingManager; |
57 |
import org.gvsig.pdf.swing.api.PDFViewer; |
58 |
import org.gvsig.tools.ToolsLocator; |
59 |
import org.gvsig.tools.locator.LocatorException; |
60 |
import org.gvsig.tools.persistence.PersistenceManager; |
61 |
import org.gvsig.tools.persistence.PersistentState; |
62 |
import org.gvsig.tools.resourcesstorage.ResourcesStorage; |
63 |
import org.gvsig.tools.swing.api.ToolsSwingLocator; |
64 |
import org.gvsig.tools.swing.api.ToolsSwingUtils; |
65 |
import org.gvsig.tools.swing.api.windowmanager.WindowManager; |
66 |
import org.gvsig.tools.util.ToolsUtilLocator; |
67 |
|
68 |
/**
|
69 |
*
|
70 |
* @author jjdelcerro
|
71 |
*/
|
72 |
@SuppressWarnings("UseSpecificCatch") |
73 |
public class LayoutReportActionImpl extends AbstractReportAction implements LayoutReportAction { |
74 |
|
75 |
public static LayoutReportActionImpl createFakeLayoutReportAction(Document doc) { |
76 |
ApplicationManager application = ApplicationLocator.getApplicationManager(); |
77 |
DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager(); |
78 |
Feature f = null;
|
79 |
FeatureStore theStore = null;
|
80 |
ReportActionFactory theFactory = dataSwingManager.getReportActionFactory(LAYOUT_REPORT_ACTION_NAME); |
81 |
try {
|
82 |
IWindow activeView = application.getActiveWindow(ViewDocument.class); |
83 |
ViewDocument viewdoc = (ViewDocument) ((IView)activeView).getDocument(); |
84 |
FLyrVect layer = viewdoc.getMapContext().getLayers().getFirstActiveVectorLayer(); |
85 |
theStore = layer.getFeatureStore(); |
86 |
if( theStore.isFeatureSelectionEmpty() ) {
|
87 |
f = theStore.first(); |
88 |
} else {
|
89 |
f = theStore.getFeatureSelection().first(); |
90 |
} |
91 |
} catch(Throwable t) { |
92 |
LOGGER.debug("Can't retrieve test feature",t);
|
93 |
} |
94 |
LayoutReportActionImpl report = new LayoutReportActionImpl(theFactory, theStore, f);
|
95 |
report.getSymbolTable().setVar("$LAYOUT", doc);
|
96 |
report.getSymbolTable().setVar("$PAGE", 1); |
97 |
report.getSymbolTable().setVar("$PAGES", 1); |
98 |
return report;
|
99 |
} |
100 |
|
101 |
|
102 |
private final JsonObject json; |
103 |
private final FeatureStore store; |
104 |
private final FeatureQuery query; |
105 |
private FeatureSet selection;
|
106 |
private Feature current_row;
|
107 |
private MutableSymbolTable symbolTable;
|
108 |
FeatureSymbolTable fSymbolTable; |
109 |
private boolean centerToCurrentRow; |
110 |
private boolean zoomToCurrentRow; |
111 |
private int bufferSize; |
112 |
private boolean selectCurrentRow; |
113 |
private boolean useInternalPdfViewer; |
114 |
// private FeatureSet set;
|
115 |
private Iterable<Feature> set; |
116 |
private int featuresCount; |
117 |
private String viewTag; |
118 |
|
119 |
@SuppressWarnings("OverridableMethodCallInConstructor") |
120 |
private LayoutReportActionImpl(ReportActionFactory factory, FeatureStore store, Feature feature) {
|
121 |
// Fake layoutReportAction constructor
|
122 |
super(factory, null); |
123 |
try {
|
124 |
this.selection = store.createFeatureSelection();
|
125 |
((FeatureSelection)this.selection).select(feature);
|
126 |
} catch(Throwable t) { |
127 |
LOGGER.debug("Can't initialize selection",t);
|
128 |
} |
129 |
this.store = store;
|
130 |
this.query = store.createFeatureQuery(feature.createFilter());
|
131 |
this.current_row = feature;
|
132 |
this.json = Json.createObjectBuilder()
|
133 |
.add(LAYOUT_REPORT_NAME, store.getName()) |
134 |
.add(LAYOUT_REPORT_TYPE, LAYOUT_REPORT_ACTION_NAME) |
135 |
.add(LAYOUT_REPORT_LABEL, store.getName()) |
136 |
.build(); |
137 |
|
138 |
this.setReportName(this.json.getString(LAYOUT_REPORT_NAME, store.getName())); |
139 |
this.setReportLabel(this.json.getString(LAYOUT_REPORT_LABEL, this.getReportName())); |
140 |
} |
141 |
|
142 |
@SuppressWarnings("OverridableMethodCallInConstructor") |
143 |
public LayoutReportActionImpl(ReportActionFactory factory, FeatureStore store, FeatureQuery query, FeatureSet selection, final JsonObject json) { |
144 |
super(factory, null); |
145 |
this.json = json;
|
146 |
this.setReportName(this.json.getString(LAYOUT_REPORT_NAME, store.getName())); |
147 |
this.setReportLabel(this.json.getString(LAYOUT_REPORT_LABEL, this.getReportName())); |
148 |
|
149 |
this.setCenterToCurrentRow(this.json.getBoolean(LAYOUT_REPORT_CENTER_TO_CURRENT_ROW, true)); |
150 |
this.setZoomToCurrentRow(this.json.getBoolean(LAYOUT_REPORT_ZOOM_TO_CURRENT_ROW, true)); |
151 |
this.setBufferSize(this.json.getInt(LAYOUT_REPORT_BUFFER_SIZE, 0)); |
152 |
this.setSelectCurrentRow(this.json.getBoolean(LAYOUT_REPORT_SELECT_CURRENT_ROW, false)); |
153 |
this.setViewTag(this.json.getString(LAYOUT_REPORT_VIEW_TAG, null)); |
154 |
this.setUseInternalPdfViewer(this.json.getBoolean(LAYOUT_REPORT_USE_INTERNAL_PDF_VIEWER, true)); |
155 |
|
156 |
this.selection = selection;
|
157 |
this.store = store;
|
158 |
this.query = query;
|
159 |
this.current_row = null; |
160 |
} |
161 |
|
162 |
public Feature row() {
|
163 |
return this.current_row; |
164 |
} |
165 |
|
166 |
private Iterable<Feature> features() { |
167 |
if( this.set == null ) { |
168 |
if(this.selection == null){ |
169 |
try {
|
170 |
FeatureSet fset = store.getFeatureSet(query); |
171 |
this.featuresCount = fset.size();
|
172 |
this.set = fset;
|
173 |
} catch (DataException ex) {
|
174 |
throw new RuntimeException("Can't create dynamic-text report.", ex); |
175 |
} |
176 |
} else {
|
177 |
this.featuresCount = this.selection.size(); |
178 |
if(this.selection instanceof FeatureSelection){ |
179 |
this.set = this.store.getFeaturesIterable(((FeatureSelection)this.selection).referenceIterator()); |
180 |
} else {
|
181 |
this.set = this.selection; |
182 |
} |
183 |
} |
184 |
} |
185 |
return this.set; |
186 |
} |
187 |
|
188 |
|
189 |
@Override
|
190 |
public void actionPerformed(ActionEvent e) { |
191 |
try {
|
192 |
String title = this.getReportLabel(); |
193 |
String creator = "gvSIG-desktop"; |
194 |
String subject = "Layout report"; |
195 |
|
196 |
File pdfFile = ToolsLocator.getFoldersManager().getUniqueTemporaryFile("report.pdf"); |
197 |
List<File> singlePdfFiles = new ArrayList(); |
198 |
int pag = 0; |
199 |
for (Feature feature : features()) {
|
200 |
File f = printReport(feature,++pag);
|
201 |
singlePdfFiles.add(f); |
202 |
} |
203 |
|
204 |
PDFManager pdfManager = PDFLocator.getPDFManager(); |
205 |
pdfManager.merge(singlePdfFiles, pdfFile, title, creator, subject); |
206 |
|
207 |
for (File singlePdfFile : singlePdfFiles) { |
208 |
singlePdfFile.delete(); |
209 |
} |
210 |
|
211 |
if (this.isUseInternalPdfViewer()) { |
212 |
this.showEmbedded(pdfFile);
|
213 |
} else {
|
214 |
this.showExternal(pdfFile);
|
215 |
} |
216 |
|
217 |
this.getStatus().terminate();
|
218 |
|
219 |
} catch (Throwable t) { |
220 |
LOGGER.warn("Can't create layout report.", t);
|
221 |
this.getStatus().abort();
|
222 |
} |
223 |
} |
224 |
|
225 |
private File printReport(Feature feature, int page) throws Exception { |
226 |
this.current_row = feature;
|
227 |
final LayoutPanel layout = this.loadTemplate(); |
228 |
final LayoutContext context = layout.getLayoutContext();
|
229 |
final Document document = layout.getDocument(); |
230 |
|
231 |
this.getSymbolTable();
|
232 |
fSymbolTable.setFeature(current_row); |
233 |
this.symbolTable.setVar("$LAYOUT", document); |
234 |
this.symbolTable.setVar("$PAGE", page); |
235 |
this.symbolTable.setVar("$PAGES", this.featuresCount); |
236 |
|
237 |
|
238 |
File pdfFile = null; |
239 |
Object previous_report = document.getProperty("$REPORT"); |
240 |
try {
|
241 |
document.setProperty("$REPORT", this); |
242 |
/*
|
243 |
TODO: Aqui podriamos consultar en el json para ver si hacemos:
|
244 |
x zoom al envelope de la geometria de current_row,
|
245 |
x si le aplicamos un buffer antes a ese envelop,
|
246 |
X si la seleccionamos...
|
247 |
- asi como con que vista tenemos que hacerlo. ????
|
248 |
*/
|
249 |
int count = 1; |
250 |
MapContext mapContext = null;
|
251 |
MapContext mapContextCandidate = null;
|
252 |
for (IFFrame frame : context.getAllFFrames()) {
|
253 |
if (frame instanceof FFrameView) { |
254 |
if(mapContextCandidate == null){ |
255 |
mapContextCandidate = ((FFrameView) frame).getMapContext(); |
256 |
} |
257 |
String frameTag = frame.getTag();
|
258 |
String countTag = "#"+count; |
259 |
if(StringUtils.equalsIgnoreCase(this.getViewTag(), frameTag) || |
260 |
StringUtils.equalsIgnoreCase(this.getViewTag(), countTag)){
|
261 |
mapContext = ((FFrameView) frame).getMapContext(); |
262 |
break;
|
263 |
} |
264 |
} |
265 |
} |
266 |
if(mapContext == null){ |
267 |
mapContext = mapContextCandidate; |
268 |
}; |
269 |
|
270 |
FeatureStore storeInLayout = this.store;
|
271 |
if (mapContext != null) { |
272 |
Envelope envelope = mapContext.getViewPort().getEnvelope(); |
273 |
if (isZoomToCurrentRow()) {
|
274 |
|
275 |
envelope = this.current_row.getDefaultGeometry()
|
276 |
.getEnvelope().getGeometry().buffer(getBufferSize()).getEnvelope(); |
277 |
mapContext.getViewPort().setEnvelope(envelope); |
278 |
|
279 |
} else if (isCenterToCurrentRow()) { |
280 |
|
281 |
envelope = this.current_row.getDefaultGeometry()
|
282 |
.getEnvelope().getGeometry().buffer(getBufferSize()).getEnvelope(); |
283 |
|
284 |
center(mapContext, envelope); |
285 |
|
286 |
} else {
|
287 |
//DO NOTHING ??
|
288 |
} |
289 |
/*
|
290 |
FIXME: Habria que localizar el store en la vista y buscar ahi
|
291 |
la current_row para seleccionarla. Seleccionando directamente
|
292 |
la del store puede no funcionar por no ser el mismo store.
|
293 |
*/
|
294 |
for (FLayer layer : mapContext.getLayers().getLayers(null)) { |
295 |
if (layer instanceof FLyrVect) { |
296 |
FeatureStore layerStore = ((FLyrVect) layer).getFeatureStore(); |
297 |
if (layerStore != null) { |
298 |
if (layerStore.getParameters().isTheSameStore(this.store.getParameters())) { |
299 |
storeInLayout = layerStore; |
300 |
} |
301 |
} |
302 |
} |
303 |
} |
304 |
} |
305 |
storeInLayout.getFeatureSelection().deselectAll(); |
306 |
if (isSelectCurrentRow()) {
|
307 |
storeInLayout.getFeatureSelection().select(current_row.getReference()); |
308 |
} |
309 |
|
310 |
context.fullRefresh(); |
311 |
layout.getLayoutControl().getLayoutDraw().initialize(); |
312 |
|
313 |
pdfFile = ToolsLocator.getFoldersManager().getUniqueTemporaryFile("report.pdf");
|
314 |
layout.layoutToPDF(pdfFile); |
315 |
} finally {
|
316 |
document.setProperty("$REPORT", previous_report);
|
317 |
} |
318 |
|
319 |
return pdfFile;
|
320 |
} |
321 |
|
322 |
private void center(MapContext mapContext, Envelope envelope) throws LocatorException, CreateEnvelopeException { |
323 |
ViewPort viewPort = mapContext.getViewPort(); |
324 |
Envelope oldExtent = viewPort.getAdjustedEnvelope(); |
325 |
double oldCenterX = oldExtent.getCenter(0); |
326 |
double oldCenterY = oldExtent.getCenter(1); |
327 |
double centerX = envelope.getCenter(0); |
328 |
double centerY = envelope.getCenter(1); |
329 |
Point2D.Double center = new Point2D.Double(centerX, centerY); |
330 |
double movX = centerX - oldCenterX;
|
331 |
double movY = centerY - oldCenterY;
|
332 |
|
333 |
double minx = oldExtent.getMinimum(0) + movX; |
334 |
double miny = oldExtent.getMinimum(1) + movY; |
335 |
double maxX = oldExtent.getMaximum(0) + movX; |
336 |
double maxY = oldExtent.getMaximum(1) + movY; |
337 |
Envelope extent = GeometryLocator.getGeometryManager().createEnvelope( |
338 |
minx, miny, |
339 |
maxX, maxY, |
340 |
Geometry.SUBTYPES.GEOM2D); |
341 |
viewPort.setEnvelope(extent); |
342 |
} |
343 |
|
344 |
private void showEmbedded(File pdfFile) throws IOException { |
345 |
final WindowManager windowManager = ToolsSwingLocator.getWindowManager();
|
346 |
final PDFSwingManager pdfSwingManager = PDFSwingLocator.getPDFSwingManager();
|
347 |
final PDFManager pdfManager = PDFLocator.getPDFManager();
|
348 |
|
349 |
final PDFDocument pdfdoc = pdfManager.createPDFDocument(pdfFile);
|
350 |
PDFViewer viewer = pdfSwingManager.createPDFViewer(); |
351 |
viewer.put(pdfdoc); |
352 |
viewer.setMode(PDFViewer.MODE_LIGHT); |
353 |
|
354 |
JComponent comp = viewer.asJComponent();
|
355 |
Dimension size = ToolsSwingUtils.ensureRowsCols(comp.getPreferredSize(), 20, 100, 40, 150); |
356 |
comp.setSize(size); |
357 |
|
358 |
String title = "Report: " + this.getLabel(); |
359 |
windowManager.showWindow( |
360 |
comp, |
361 |
title, |
362 |
WindowManager.MODE.WINDOW |
363 |
); |
364 |
} |
365 |
|
366 |
private void showExternal(File pdfFile) { |
367 |
DesktopOpen desktop = ToolsUtilLocator.getToolsUtilManager().createDesktopOpen(); |
368 |
desktop.open(pdfFile); |
369 |
} |
370 |
|
371 |
private LayoutPanel loadTemplate() throws Exception { |
372 |
ResourcesStorage resources = store.getResourcesStorage(); |
373 |
if (resources == null) { |
374 |
return null; |
375 |
} |
376 |
String templateName = this.json.getString(LAYOUT_REPORT_TEMPLATE_NAME, LAYOUT_REPORT_DEFAULT_TEMPLATE_NAME); // "1.layout"... |
377 |
ResourcesStorage.Resource resource = resources.getResource(templateName); |
378 |
InputStream is = null; |
379 |
try {
|
380 |
is = resource.asInputStream(); |
381 |
PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager(); |
382 |
PersistentState persistentState = persistenceManager.loadState(is); |
383 |
|
384 |
LayoutPanel layout = (LayoutPanel) persistenceManager.create(persistentState); |
385 |
|
386 |
return layout;
|
387 |
} finally {
|
388 |
IOUtils.closeQuietly(is); |
389 |
} |
390 |
} |
391 |
|
392 |
public MutableSymbolTable getSymbolTable() {
|
393 |
if( this.symbolTable == null ) { |
394 |
this.symbolTable = ExpressionUtils.createSymbolTable();
|
395 |
fSymbolTable = DALLocator.getDataManager().createFeatureSymbolTable(); |
396 |
fSymbolTable.setFeature(current_row); |
397 |
this.symbolTable.addSymbolTable(fSymbolTable);
|
398 |
this.symbolTable.setVar("$REPORT", this); |
399 |
} |
400 |
return this.symbolTable; |
401 |
} |
402 |
|
403 |
@Override
|
404 |
public String evaluateDynamicText(String s) { |
405 |
ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager(); |
406 |
if( !manager.isDynamicText(s) ) {
|
407 |
return s;
|
408 |
} |
409 |
String x = manager.evaluateDynamicText(
|
410 |
this.getSymbolTable(),
|
411 |
s, |
412 |
null,
|
413 |
this.store.getResourcesStorage()
|
414 |
); |
415 |
return x;
|
416 |
} |
417 |
|
418 |
@Override
|
419 |
public boolean isCenterToCurrentRow() { |
420 |
return this.centerToCurrentRow; |
421 |
} |
422 |
|
423 |
@Override
|
424 |
public void setCenterToCurrentRow(boolean centerToCurrentRow) { |
425 |
this.centerToCurrentRow = centerToCurrentRow;
|
426 |
} |
427 |
|
428 |
@Override
|
429 |
public boolean isZoomToCurrentRow() { |
430 |
return this.zoomToCurrentRow; |
431 |
} |
432 |
|
433 |
@Override
|
434 |
public void setZoomToCurrentRow(boolean zoomToCurrentRow) { |
435 |
this.zoomToCurrentRow = zoomToCurrentRow;
|
436 |
} |
437 |
|
438 |
@Override
|
439 |
public int getBufferSize() { |
440 |
return bufferSize;
|
441 |
} |
442 |
|
443 |
@Override
|
444 |
public void setBufferSize(int bufferSize) { |
445 |
this.bufferSize = bufferSize;
|
446 |
} |
447 |
|
448 |
@Override
|
449 |
public boolean isSelectCurrentRow() { |
450 |
return selectCurrentRow;
|
451 |
} |
452 |
|
453 |
@Override
|
454 |
public void setSelectCurrentRow(boolean selectCurrentRow) { |
455 |
this.selectCurrentRow = selectCurrentRow;
|
456 |
} |
457 |
|
458 |
@Override
|
459 |
public String getViewTag() { |
460 |
return viewTag;
|
461 |
} |
462 |
|
463 |
@Override
|
464 |
public void setViewTag(String viewTag) { |
465 |
this.viewTag = viewTag;
|
466 |
} |
467 |
|
468 |
public boolean isUseInternalPdfViewer() { |
469 |
return useInternalPdfViewer;
|
470 |
} |
471 |
|
472 |
@Override
|
473 |
public void setUseInternalPdfViewer(boolean useInternalPdfViewer) { |
474 |
this.useInternalPdfViewer = useInternalPdfViewer;
|
475 |
} |
476 |
|
477 |
} |