| /* |
| * Copyright (c) 2009, Tony Kohar. All Rights Reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| * implied. |
| * |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.qi4j.envisage.print; |
| |
| import java.awt.Component; |
| import java.awt.image.BufferedImage; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.ParameterizedType; |
| import java.lang.reflect.Type; |
| import java.lang.reflect.TypeVariable; |
| import java.lang.reflect.WildcardType; |
| import java.util.HashSet; |
| import java.util.List; |
| import javax.imageio.ImageIO; |
| import javax.swing.JFileChooser; |
| import javax.swing.filechooser.FileFilter; |
| import org.apache.pdfbox.exceptions.COSVisitorException; |
| import org.apache.pdfbox.pdmodel.PDDocument; |
| import org.apache.pdfbox.pdmodel.PDPage; |
| import org.apache.pdfbox.pdmodel.common.PDRectangle; |
| import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; |
| import org.apache.pdfbox.pdmodel.font.PDFont; |
| import org.apache.pdfbox.pdmodel.font.PDType1Font; |
| import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg; |
| import org.qi4j.api.composite.CompositeDescriptor; |
| import org.qi4j.api.composite.DependencyDescriptor; |
| import org.qi4j.api.composite.ModelDescriptor; |
| import org.qi4j.api.entity.EntityDescriptor; |
| import org.qi4j.api.object.ObjectDescriptor; |
| import org.qi4j.api.service.ImportedServiceDescriptor; |
| import org.qi4j.api.service.ServiceDescriptor; |
| import org.qi4j.api.service.ServiceImporter; |
| import org.qi4j.api.value.ValueDescriptor; |
| import org.qi4j.envisage.graph.GraphDisplay; |
| import org.qi4j.envisage.util.TableRow; |
| import org.qi4j.envisage.util.TableRowUtilities; |
| import org.qi4j.tools.model.descriptor.*; |
| import org.qi4j.tools.model.util.DescriptorUtilities; |
| |
| public class PDFWriter |
| { |
| protected PDDocument doc = null; |
| protected PDPageContentStream curContentStream = null; |
| protected PDRectangle curPageSize; |
| protected float curY; |
| protected PDFont curFont; |
| protected float curFontSize; |
| |
| protected String APPLICATION = "Application"; |
| protected String LAYER = "Layer"; |
| protected String MODULE = "Module"; |
| |
| protected PDFont normalFont = PDType1Font.HELVETICA; |
| protected PDFont header1Font = PDType1Font.HELVETICA_BOLD; // Application |
| protected PDFont header2Font = PDType1Font.HELVETICA_BOLD; // Layer |
| protected PDFont header3Font = PDType1Font.HELVETICA_BOLD; // Module |
| protected PDFont header4Font = PDType1Font.HELVETICA_BOLD; // Type Container |
| protected PDFont header5Font = PDType1Font.HELVETICA_BOLD_OBLIQUE; // Type |
| protected float normalFontSize = 10; |
| protected float header1FontSize = 18; |
| protected float header2FontSize = 16; |
| protected float header3FontSize = 14; |
| protected float header4FontSize = 12; |
| protected float header5FontSize = 12; |
| |
| protected float startX = 40; |
| protected float startY = 40; |
| protected float lineSpace = 15; |
| protected float headerLineSpace = 25; |
| |
| public void write( Component parent, ApplicationDetailDescriptor descriptor, List<GraphDisplay> graphDisplays ) |
| { |
| JFileChooser fc = new JFileChooser(); |
| PDFFileFilter pdfFileFilter = new PDFFileFilter(); |
| fc.setFileFilter( pdfFileFilter ); |
| |
| int choice = fc.showSaveDialog( parent ); |
| if( choice != JFileChooser.APPROVE_OPTION ) |
| { |
| return; |
| } |
| |
| File file = fc.getSelectedFile(); |
| String filename = file.toString(); |
| String ext = ".pdf"; |
| if( !filename.endsWith( ext ) ) |
| { |
| filename = filename + ext; |
| file = new File( filename ); |
| } |
| |
| write( file, descriptor, graphDisplays ); |
| } |
| |
| public void write( File file, ApplicationDetailDescriptor descriptor, List<GraphDisplay> graphDisplays ) |
| { |
| try |
| { |
| writeImpl( file, descriptor, graphDisplays ); |
| } |
| catch( IOException | COSVisitorException ex ) |
| { |
| ex.printStackTrace(); |
| } |
| } |
| |
| protected void writeImpl( File file, ApplicationDetailDescriptor descriptor, List<GraphDisplay> graphDisplays ) |
| throws IOException, COSVisitorException |
| { |
| try |
| { |
| doc = new PDDocument(); |
| for( GraphDisplay graphDisplay : graphDisplays ) |
| { |
| writeGraphPage( graphDisplay ); |
| } |
| writePage( descriptor ); |
| if( curContentStream != null ) |
| { |
| curContentStream.close(); |
| curContentStream = null; |
| } |
| doc.save( new FileOutputStream( file ) ); |
| } |
| finally |
| { |
| if( curContentStream != null ) |
| { |
| curContentStream.close(); |
| curContentStream = null; |
| } |
| |
| if( doc != null ) |
| { |
| doc.close(); |
| doc = null; |
| } |
| } |
| } |
| |
| private void writeGraphPage( GraphDisplay graphDisplay ) |
| throws IOException |
| { |
| File tFile = File.createTempFile( "envisage", "png" ); |
| graphDisplay.saveImage( new FileOutputStream( tFile ), "png", 1d ); |
| |
| BufferedImage img = ImageIO.read( tFile ); |
| |
| int w = img.getWidth(); |
| int h = img.getHeight(); |
| |
| int inset = 40; |
| PDRectangle pdRect = new PDRectangle( w + inset, h + inset ); |
| PDPage page = new PDPage(); |
| page.setMediaBox( pdRect ); |
| doc.addPage( page ); |
| |
| PDJpeg xImage = new PDJpeg( doc, img ); |
| |
| PDPageContentStream contentStream = new PDPageContentStream( doc, page ); |
| contentStream.drawImage( xImage, ( pdRect.getWidth() - w ) / 2, ( pdRect.getHeight() - h ) / 2 ); |
| contentStream.close(); |
| } |
| |
| private void writePage( ApplicationDetailDescriptor descriptor ) |
| { |
| createNewPage(); |
| setFont( header1Font, header1FontSize ); |
| writeString( APPLICATION + " : " + descriptor.toString() ); |
| |
| writeLayersPage( descriptor.layers() ); |
| } |
| |
| private void writeLayersPage( Iterable<LayerDetailDescriptor> iter ) |
| { |
| for( LayerDetailDescriptor descriptor : iter ) |
| { |
| setFont( header2Font, header2FontSize ); |
| writeString( LAYER + " : " + descriptor.toString(), headerLineSpace ); |
| |
| writeModulesPage( descriptor.modules() ); |
| } |
| } |
| |
| private void writeModulesPage( Iterable<ModuleDetailDescriptor> iter ) |
| { |
| for( ModuleDetailDescriptor descriptor : iter ) |
| { |
| setFont( header3Font, header3FontSize ); |
| writeString( MODULE + " : " + descriptor.toString(), headerLineSpace ); |
| |
| writeServicesPage( descriptor.services() ); |
| writeImportedServicesPage( descriptor.importedServices() ); |
| writeEntitiesPage( descriptor.entities() ); |
| writeTransientsPage( descriptor.transients() ); |
| writeValuesPage( descriptor.values() ); |
| writeObjectsPage( descriptor.objects() ); |
| } |
| } |
| |
| private void writeServicesPage( Iterable<ServiceDetailDescriptor> iter ) |
| { |
| for( ServiceDetailDescriptor descriptor : iter ) |
| { |
| setFont( header4Font, header4FontSize ); |
| writeString( descriptor.toString(), headerLineSpace ); |
| writeTypeGeneralPage( descriptor ); |
| writeTypeDependenciesPage( descriptor ); |
| writeTypeMethodsPage( descriptor ); |
| writeTypeStatesPage( descriptor ); |
| writeTypeServiceConfigurationPage( descriptor ); |
| writeTypeServiceUsagePage( descriptor ); |
| } |
| } |
| |
| private void writeImportedServicesPage( Iterable<ImportedServiceDetailDescriptor> iter ) |
| { |
| for( ImportedServiceDetailDescriptor descriptor : iter ) |
| { |
| setFont( header4Font, header4FontSize ); |
| writeString( descriptor.toString(), headerLineSpace ); |
| writeTypeGeneralPage( descriptor ); |
| writeTypeMethodsPage( descriptor ); |
| writeTypeServiceUsagePage( descriptor ); |
| writeTypeImportedByPage( descriptor ); |
| } |
| } |
| |
| private void writeEntitiesPage( Iterable<EntityDetailDescriptor> iter ) |
| { |
| for( EntityDetailDescriptor descriptor : iter ) |
| { |
| setFont( header4Font, header4FontSize ); |
| writeString( descriptor.toString(), headerLineSpace ); |
| writeTypeGeneralPage( descriptor ); |
| writeTypeDependenciesPage( descriptor ); |
| writeTypeMethodsPage( descriptor ); |
| writeTypeStatesPage( descriptor ); |
| } |
| } |
| |
| private void writeTransientsPage( Iterable<TransientDetailDescriptor> iter ) |
| { |
| for( TransientDetailDescriptor descriptor : iter ) |
| { |
| setFont( header4Font, header4FontSize ); |
| writeString( descriptor.toString(), headerLineSpace ); |
| writeTypeGeneralPage( descriptor ); |
| writeTypeDependenciesPage( descriptor ); |
| writeTypeMethodsPage( descriptor ); |
| writeTypeStatesPage( descriptor ); |
| } |
| } |
| |
| private void writeValuesPage( Iterable<ValueDetailDescriptor> iter ) |
| { |
| for( ValueDetailDescriptor descriptor : iter ) |
| { |
| setFont( header4Font, header4FontSize ); |
| writeString( descriptor.toString(), headerLineSpace ); |
| writeTypeGeneralPage( descriptor ); |
| writeTypeDependenciesPage( descriptor ); |
| writeTypeMethodsPage( descriptor ); |
| writeTypeStatesPage( descriptor ); |
| } |
| } |
| |
| private void writeObjectsPage( Iterable<ObjectDetailDescriptor> iter ) |
| { |
| for( ObjectDetailDescriptor descriptor : iter ) |
| { |
| setFont( header4Font, header4FontSize ); |
| writeString( descriptor.toString(), headerLineSpace ); |
| writeTypeGeneralPage( descriptor ); |
| writeTypeDependenciesPage( descriptor ); |
| // object don't have methods |
| } |
| } |
| |
| private void writeTypeGeneralPage( Object objectDesciptor ) |
| { |
| |
| setFont( header5Font, header5FontSize ); |
| writeString( "General: ", headerLineSpace ); |
| |
| setFont( normalFont, normalFontSize ); |
| |
| if( objectDesciptor instanceof ServiceDetailDescriptor ) |
| { |
| ServiceDescriptor descriptor = ( (ServiceDetailDescriptor) objectDesciptor ).descriptor(); |
| writeString( "- identity: " + descriptor.identity() ); |
| writeString( "- class: " + descriptor.toString() ); |
| writeString( "- visibility: " + descriptor.visibility().toString() ); |
| writeString( "- startup: " + ( (ServiceDetailDescriptor) objectDesciptor ).descriptor() |
| .isInstantiateOnStartup() ); |
| } |
| else if( objectDesciptor instanceof EntityDetailDescriptor ) |
| { |
| EntityDescriptor descriptor = ( (EntityDetailDescriptor) objectDesciptor ).descriptor(); |
| writeString( "- name: " + descriptor.toString() ); |
| writeString( "- class: " + descriptor.toString() ); |
| writeString( "- visibility: " + descriptor.visibility().toString() ); |
| } |
| else if( objectDesciptor instanceof ValueDetailDescriptor ) |
| { |
| ValueDescriptor descriptor = ( (ValueDetailDescriptor) objectDesciptor ).descriptor(); |
| writeString( "- name: " + descriptor.toString() ); |
| writeString( "- class: " + descriptor.toString() ); |
| writeString( "- visibility: " + descriptor.visibility().toString() ); |
| } |
| else if( objectDesciptor instanceof ObjectDetailDescriptor ) |
| { |
| ObjectDescriptor descriptor = ( (ObjectDetailDescriptor) objectDesciptor ).descriptor(); |
| writeString( "- name: " + descriptor.toString() ); |
| writeString( "- class: " + descriptor.toString() ); |
| writeString( "- visibility: " + descriptor.visibility().toString() ); |
| } |
| else if( objectDesciptor instanceof CompositeDetailDescriptor ) |
| { |
| CompositeDescriptor descriptor = ( (CompositeDetailDescriptor) objectDesciptor ).descriptor(); |
| writeString( "- name: " + descriptor.toString() ); |
| writeString( "- class: " + descriptor.toString() ); |
| writeString( "- visibility: " + descriptor.visibility().toString() ); |
| } |
| } |
| |
| private void writeTypeDependenciesPage( Object objectDesciptor ) |
| { |
| setFont( header5Font, header5FontSize ); |
| writeString( "Dependencies: ", headerLineSpace ); |
| |
| if( objectDesciptor instanceof CompositeDetailDescriptor ) |
| { |
| CompositeDetailDescriptor descriptor = (CompositeDetailDescriptor) objectDesciptor; |
| Iterable<MixinDetailDescriptor> iter = descriptor.mixins(); |
| for( MixinDetailDescriptor mixinDescriptor : iter ) |
| { |
| writeTypeDependenciesPage( mixinDescriptor.injectedFields() ); |
| } |
| } |
| else if( objectDesciptor instanceof ObjectDetailDescriptor ) |
| { |
| ObjectDetailDescriptor descriptor = ( (ObjectDetailDescriptor) objectDesciptor ); |
| writeTypeDependenciesPage( descriptor.injectedFields() ); |
| } |
| } |
| |
| private void writeTypeDependenciesPage( Iterable<InjectedFieldDetailDescriptor> iter ) |
| { |
| setFont( normalFont, normalFontSize ); |
| for( InjectedFieldDetailDescriptor descriptor : iter ) |
| { |
| DependencyDescriptor dependencyDescriptor = descriptor.descriptor().dependency(); |
| writeString( "- name: " + dependencyDescriptor.injectedClass().getSimpleName() ); |
| writeString( " * annotation: @" + dependencyDescriptor.injectionAnnotation() |
| .annotationType() |
| .getSimpleName() ); |
| writeString( " * optional: " + Boolean.toString( dependencyDescriptor.optional() ) ); |
| writeString( " * type: " + dependencyDescriptor.injectionType().getClass().getSimpleName() ); |
| } |
| } |
| |
| private void writeTypeMethodsPage( Object objectDesciptor ) |
| { |
| if( !CompositeDetailDescriptor.class.isAssignableFrom( objectDesciptor.getClass() ) ) |
| { |
| return; |
| } |
| |
| setFont( header5Font, header5FontSize ); |
| writeString( "Methods: ", headerLineSpace ); |
| setFont( normalFont, normalFontSize ); |
| |
| CompositeDetailDescriptor descriptor = (CompositeDetailDescriptor) objectDesciptor; |
| List<CompositeMethodDetailDescriptor> list = DescriptorUtilities.findMethod( descriptor ); |
| |
| HashSet<String> imports = new HashSet<>(); |
| for( CompositeMethodDetailDescriptor methodDescriptor : list ) |
| { |
| addImport( imports, methodDescriptor.descriptor().method().getGenericReturnType() ); |
| for( Class parameter : methodDescriptor.descriptor().method().getParameterTypes() ) |
| { |
| addImport( imports, parameter ); |
| } |
| } |
| for( String imp : imports ) |
| { |
| writeString( " import " + imp + ";" ); |
| } |
| writeString( "" ); |
| |
| for( CompositeMethodDetailDescriptor methodDescriptor : list ) |
| { |
| Type returnType = methodDescriptor.descriptor().method().getGenericReturnType(); |
| writeString( " " + formatType( returnType ) + "." |
| + methodDescriptor.toString() |
| + formatParameters( methodDescriptor.descriptor().method().getParameterTypes() ) |
| ); |
| } |
| } |
| |
| private String formatParameters( Class<?>[] parameterTypes ) |
| { |
| StringBuilder result = new StringBuilder(); |
| result.append( "(" ); |
| boolean first = true; |
| int count = 1; |
| for( Class parameter : parameterTypes ) |
| { |
| if( !first ) |
| { |
| result.append( "," ); |
| } |
| first = false; |
| result.append( " " ); |
| result.append( formatType( parameter ) ); |
| result.append( " " ); |
| result.append( "p" ); |
| result.append( count++ ); |
| } |
| if( first ) |
| { |
| // No parameters appended. |
| result.append( ");" ); |
| } |
| else |
| { |
| result.append( " );" ); |
| } |
| return result.toString(); |
| } |
| |
| private String formatType( Type type ) |
| { |
| if( type instanceof Class ) |
| { |
| Class clazz = (Class) type; |
| return clazz.getSimpleName(); |
| } |
| else if( type instanceof ParameterizedType ) |
| { |
| ParameterizedType pType = (ParameterizedType) type; |
| Type[] actuals = pType.getActualTypeArguments(); |
| Type ownerType = pType.getOwnerType(); |
| Type rawType = pType.getRawType(); |
| StringBuilder result = new StringBuilder(); |
| result.append( ( (Class) rawType ).getSimpleName() ); |
| result.append( "<" ); |
| boolean first = true; |
| for( Type actual : actuals ) |
| { |
| if( !first ) |
| { |
| result.append( "," ); |
| } |
| first = false; |
| result.append( formatType( actual ) ); |
| } |
| result.append( ">" ); |
| |
| return result.toString(); |
| } |
| else if( type instanceof WildcardType ) |
| { |
| // TODO: I am sure there are other wildcard constructs that will format incorrectly. Fix that! |
| // |
| WildcardType wildcard = (WildcardType) type; |
| Type[] lowers = wildcard.getLowerBounds(); |
| Type[] uppers = wildcard.getUpperBounds(); |
| StringBuilder result = new StringBuilder(); |
| result.append( "? extends " ); |
| boolean first = true; |
| for( Type upper : uppers ) |
| { |
| if( !first ) |
| { |
| result.append( ", " ); |
| } |
| result.append( formatType( upper ) ); |
| } |
| return result.toString(); |
| } |
| else if( type instanceof TypeVariable ) |
| { |
| return type.toString(); |
| } |
| |
| return type.toString(); |
| } |
| |
| private void addImport( HashSet<String> imports, Type type ) |
| { |
| if( type instanceof Class ) |
| { |
| Class clazz = (Class) type; |
| Package pkkage = clazz.getPackage(); |
| if( pkkage == null ) |
| { |
| return; |
| } |
| String packageName = pkkage.getName(); |
| if( packageName.startsWith( "java" ) ) |
| { |
| return; |
| } |
| imports.add( clazz.getName() ); |
| } |
| else if( type instanceof ParameterizedType ) |
| { |
| ParameterizedType pType = (ParameterizedType) type; |
| Type[] actuals = pType.getActualTypeArguments(); |
| Type ownerType = pType.getOwnerType(); |
| Type rawType = pType.getRawType(); |
| addImport( imports, ownerType ); |
| addImport( imports, rawType ); |
| for( Type actual : actuals ) |
| { |
| addImport( imports, actual ); |
| } |
| } |
| } |
| |
| private void writeTypeStatesPage( Object objectDesciptor ) |
| { |
| if( !CompositeDetailDescriptor.class.isAssignableFrom( objectDesciptor.getClass() ) ) |
| { |
| return; |
| } |
| |
| setFont( header5Font, header5FontSize ); |
| writeString( "States: ", headerLineSpace ); |
| |
| CompositeDetailDescriptor descriptor = (CompositeDetailDescriptor) objectDesciptor; |
| List<CompositeMethodDetailDescriptor> list = DescriptorUtilities.findState( descriptor ); |
| |
| setFont( normalFont, normalFontSize ); |
| for( CompositeMethodDetailDescriptor methodDescriptor : list ) |
| { |
| writeString( "- name: " + methodDescriptor.toString() ); |
| writeString( " * return: " + methodDescriptor.descriptor().method().getGenericReturnType() ); |
| } |
| } |
| |
| private void writeTypeServiceConfigurationPage( Object objectDesciptor ) |
| { |
| setFont( header5Font, header5FontSize ); |
| writeString( "Configuration: ", headerLineSpace ); |
| |
| Object configDescriptor = DescriptorUtilities.findServiceConfiguration( (ServiceDetailDescriptor) objectDesciptor ); |
| |
| if( configDescriptor == null ) |
| { |
| return; |
| } |
| |
| ModelDescriptor spiDescriptor; |
| String typeString; |
| if( configDescriptor instanceof ServiceDetailDescriptor ) |
| { |
| spiDescriptor = ( (ServiceDetailDescriptor) configDescriptor ).descriptor(); |
| typeString = "Service"; |
| } |
| else if( configDescriptor instanceof EntityDetailDescriptor ) |
| { |
| spiDescriptor = ( (EntityDetailDescriptor) configDescriptor ).descriptor(); |
| typeString = "Entity"; |
| } |
| else if( configDescriptor instanceof ValueDetailDescriptor ) |
| { |
| spiDescriptor = ( (ValueDetailDescriptor) configDescriptor ).descriptor(); |
| typeString = "Value"; |
| } |
| else if( configDescriptor instanceof ObjectDetailDescriptor ) |
| { |
| spiDescriptor = ( (ObjectDetailDescriptor) configDescriptor ).descriptor(); |
| typeString = "Object"; |
| } |
| else if( configDescriptor instanceof CompositeDetailDescriptor ) |
| { |
| spiDescriptor = ( (CompositeDetailDescriptor) configDescriptor ).descriptor(); |
| typeString = "Transient"; |
| } |
| else |
| { |
| throw new PrintingException( "Unknown configuration descriptor: " + configDescriptor.getClass() |
| .getName(), null ); |
| } |
| |
| setFont( normalFont, normalFontSize ); |
| writeString( "- name: " + spiDescriptor.toString() ); |
| writeString( "- class: " + spiDescriptor.toString() ); |
| writeString( "- type: " + typeString ); |
| } |
| |
| private void writeTypeServiceUsagePage( Object objectDesciptor ) |
| { |
| setFont( header5Font, header5FontSize ); |
| writeString( "Usage: ", headerLineSpace ); |
| |
| setFont( normalFont, normalFontSize ); |
| List<ServiceUsage> serviceUsages = DescriptorUtilities.findServiceUsage( (ServiceDetailDescriptor) objectDesciptor ); |
| List<TableRow> rows = TableRowUtilities.toTableRows( serviceUsages ); |
| for( TableRow row : rows ) |
| { |
| |
| //String owner; |
| String usage; |
| String module; |
| String layer; |
| |
| Object obj = row.get( 0 ); |
| if( obj instanceof CompositeDetailDescriptor ) |
| { |
| CompositeDetailDescriptor descriptor = (CompositeDetailDescriptor) obj; |
| //owner = descriptor.toString(); |
| module = descriptor.module().toString(); |
| layer = descriptor.module().layer().toString(); |
| } |
| else |
| { |
| ObjectDetailDescriptor descriptor = (ObjectDetailDescriptor) obj; |
| //owner = descriptor.toString(); |
| module = descriptor.module().toString(); |
| layer = descriptor.module().layer().toString(); |
| } |
| |
| InjectedFieldDetailDescriptor injectedFieldescriptor = (InjectedFieldDetailDescriptor) row.get( 1 ); |
| DependencyDescriptor dependencyDescriptor = injectedFieldescriptor.descriptor().dependency(); |
| Annotation annotation = dependencyDescriptor.injectionAnnotation(); |
| usage = injectedFieldescriptor.toString() + " (@" + annotation.annotationType().getSimpleName() + ")"; |
| |
| writeString( "- owner: " + row.get( 0 ).toString() ); |
| writeString( " * usage: " + usage ); |
| writeString( " * module: " + module ); |
| writeString( " * layer: " + layer ); |
| } |
| } |
| |
| private void writeTypeImportedByPage( Object objectDesciptor ) |
| { |
| setFont( header5Font, header5FontSize ); |
| writeString( "Imported by: ", headerLineSpace ); |
| |
| ImportedServiceDetailDescriptor detailDescriptor = (ImportedServiceDetailDescriptor) objectDesciptor; |
| ImportedServiceDescriptor descriptor = detailDescriptor.descriptor().importedService(); |
| Class<? extends ServiceImporter> importer = descriptor.serviceImporter(); |
| |
| setFont( normalFont, normalFontSize ); |
| writeString( "- name: " + importer.getSimpleName() ); |
| writeString( "- class: " + importer.toString() ); |
| } |
| |
| private void writeString( String text ) |
| { |
| writeString( text, this.lineSpace ); |
| } |
| |
| private void writeString( String text, float lineSpace ) |
| { |
| // check for page size, if necessary create new page |
| if( ( curY - lineSpace ) <= startY ) |
| { |
| createNewPage(); |
| } |
| |
| curY = curY - lineSpace; |
| |
| try |
| { |
| curContentStream.moveTextPositionByAmount( 0, -lineSpace ); |
| curContentStream.drawString( text ); |
| } |
| catch( IOException e ) |
| { |
| throw new PrintingException( "Unable to write string: " + text, e ); |
| } |
| } |
| |
| private void setFont( PDFont font, float fontSize ) |
| { |
| curFont = font; |
| curFontSize = fontSize; |
| try |
| { |
| curContentStream.setFont( curFont, curFontSize ); |
| } |
| catch( IOException e ) |
| { |
| throw new PrintingException( "Unable to set font: " + font.toString() + ", " + fontSize + "pt", e ); |
| } |
| } |
| |
| private void createNewPage() |
| { |
| try |
| { |
| if( curContentStream != null ) |
| { |
| curContentStream.endText(); |
| curContentStream.close(); |
| } |
| |
| PDPage page = new PDPage(); |
| doc.addPage( page ); |
| |
| curContentStream = new PDPageContentStream( doc, page ); |
| |
| curPageSize = page.getArtBox(); |
| |
| curContentStream.beginText(); |
| curY = curPageSize.getHeight() - startY; |
| curContentStream.moveTextPositionByAmount( startX, curY ); |
| |
| if( curFont != null ) |
| { |
| setFont( curFont, curFontSize ); |
| } |
| } |
| catch( IOException e ) |
| { |
| throw new PrintingException( "Unable to create page.", e ); |
| } |
| } |
| |
| private double scaleToFit( double srcW, double srcH, double destW, double destH ) |
| { |
| double scale = 1; |
| if( srcW > srcH ) |
| { |
| if( srcW > destW ) |
| { |
| scale = destW / srcW; |
| } |
| srcH = srcH * scale; |
| if( srcH > destH ) |
| { |
| scale = scale * ( destH / srcH ); |
| } |
| } |
| else |
| { |
| if( srcH > destH ) |
| { |
| scale = destH / srcH; |
| } |
| srcW = srcW * scale; |
| if( srcW > destW ) |
| { |
| scale = scale * ( destW / srcW ); |
| } |
| } |
| return scale; |
| } |
| |
| static class PDFFileFilter |
| extends FileFilter |
| { |
| |
| private final String description; |
| protected String extension = null; |
| |
| public PDFFileFilter() |
| { |
| extension = "pdf"; |
| description = "PDF - Portable Document Format"; |
| } |
| |
| @Override |
| public boolean accept( File f ) |
| { |
| if( f != null ) |
| { |
| if( f.isDirectory() ) |
| { |
| return true; |
| } |
| String str = getExtension( f ); |
| if( str != null && str.equals( extension ) ) |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| public String getExtension( File f ) |
| { |
| if( f != null ) |
| { |
| String filename = f.getName(); |
| int i = filename.lastIndexOf( '.' ); |
| if( i > 0 && i < filename.length() - 1 ) |
| { |
| return filename.substring( i + 1 ).toLowerCase(); |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public String getDescription() |
| { |
| return description; |
| } |
| } |
| |
| } |