1 49 50 package org.apache.avalon.meta.info.ant; 51 52 import java.io.File ; 53 import java.io.FileOutputStream ; 54 import java.io.IOException ; 55 import java.io.OutputStream ; 56 57 import org.apache.avalon.meta.info.Service; 58 import org.apache.avalon.meta.info.Type; 59 import org.apache.avalon.meta.info.writer.SerializedServiceWriter; 60 import org.apache.avalon.meta.info.writer.SerializedTypeWriter; 61 import org.apache.avalon.meta.info.writer.ServiceWriter; 62 import org.apache.avalon.meta.info.writer.TypeWriter; 63 import org.apache.avalon.meta.info.writer.XMLServiceWriter; 64 import org.apache.avalon.meta.info.writer.XMLTypeWriter; 65 import org.apache.avalon.meta.info.builder.tags.TypeTag; 66 import org.apache.avalon.meta.info.builder.tags.ServiceTag; 67 68 import org.apache.tools.ant.BuildException; 69 70 71 import com.thoughtworks.qdox.ant.AbstractQdoxTask; 72 import com.thoughtworks.qdox.model.JavaClass; 73 74 80 public class MetaTask 81 extends AbstractQdoxTask 82 { 83 86 public static final int XML_TYPE = 0; 87 88 91 public static final int SER_TYPE = 1; 92 93 96 private static final TypeWriter XML_WRITER = new XMLTypeWriter(); 97 98 101 private static final TypeWriter SERIAL_WRITER = new SerializedTypeWriter(); 102 103 106 private static final ServiceWriter XML_SERVICE_WRITER = new XMLServiceWriter(); 107 108 111 private static final ServiceWriter SERIAL_SERVICE_WRITER = new SerializedServiceWriter(); 112 113 116 private File m_destDir; 117 118 121 private int m_format; 122 123 126 private String m_postfix = ".xinfo"; 127 128 133 private boolean m_force = true; 134 135 140 public void setDestDir( final File destDir ) 141 { 142 m_destDir = destDir; 143 } 144 145 150 public void setFormat( final FormatEnum format ) 151 { 152 m_format = format.getTypeCode(); 153 } 154 155 161 public void setForce( boolean force ) 162 { 163 m_force = force; 164 } 165 166 172 public void setPostfix( String postfix ) 173 { 174 if( postfix.equalsIgnoreCase( "xtype" ) 175 || postfix.equalsIgnoreCase( "xinfo" ) ) 176 { 177 m_postfix = "." + postfix; 178 } 179 else 180 { 181 final String error = 182 "Illegal postfix value: " + postfix + ". " 183 + "Recognized values include 'xinfo' and 'xtype'."; 184 throw new BuildException( error ); 185 } 186 } 187 188 192 public void execute() 193 throws BuildException 194 { 195 validate(); 196 197 final String message = 198 "Writing descriptors using '" 199 + getOutputDescription() 200 + "' format."; 201 log( message ); 202 203 super.execute(); 204 205 try 206 { 207 Counter counter = writeMetaData(); 208 final String update = 209 "Processed " + counter.getTypes() + " Types and " 210 + counter.getServices() + " Services from a total of " 211 + counter.getCount() + " classes."; 212 log( update ); 213 } 214 catch( final Exception e ) 215 { 216 throw new BuildException( e.toString(), e ); 217 } 218 } 219 220 223 private void validate() 224 { 225 if( null == m_destDir ) 226 { 227 final String message = 228 "DestDir (" + m_destDir + ") not specified"; 229 throw new BuildException( message ); 230 } 231 if( !m_destDir.isDirectory() ) 232 { 233 final String message = 234 "DestDir (" + m_destDir + ") is not a directory."; 235 throw new BuildException( message ); 236 } 237 238 if( !m_destDir.exists() && !m_destDir.mkdirs() ) 239 { 240 final String message = 241 "DestDir (" + m_destDir + ") could not be created."; 242 throw new BuildException( message ); 243 } 244 } 245 246 251 private String getOutputDescription() 252 { 253 if( SER_TYPE == m_format ) 254 { 255 return "serial"; 256 } 257 else 258 { 259 return "xml"; 260 } 261 } 262 263 268 private Counter writeMetaData() throws IOException 269 { 270 int services = 0; 271 int types = 0; 272 final int size = allClasses.size(); 273 for( int i = 0; i < size; i++ ) 274 { 275 final JavaClass javaClass = (JavaClass)allClasses.get( i ); 276 if( javaClass.isInterface() ) 277 { 278 Service service = new ServiceTag( javaClass ).getService(); 279 if( service == null ) 280 { 281 continue; 282 } 283 284 services++; 285 286 291 final String classname = javaClass.getFullyQualifiedName(); 292 final File source = javaClass.getParentSource().getFile(); 293 final File dest = getOutputFileForService( classname ); 294 295 if( !m_force ) 296 { 297 if( dest.exists() 298 && dest.lastModified() >= source.lastModified() ) 299 { 300 continue; 301 } 302 } 303 final File parent = dest.getParentFile(); 304 if( null != parent ) 305 { 306 if( !parent.exists() && !parent.mkdirs() ) 307 { 308 final String message = 309 "Failed to create output directory: " + parent; 310 throw new BuildException( message ); 311 } 312 } 313 writeService( service ); 314 } 315 else 316 { 317 Type type = new TypeTag( javaClass ).getType(); 318 if( type == null ) 319 { 320 continue; 321 } 322 323 types++; 324 325 330 final String classname = javaClass.getFullyQualifiedName(); 331 final File source = javaClass.getParentSource().getFile(); 332 final File dest = getOutputFileForClass( classname ); 333 334 if( !m_force ) 335 { 336 if( dest.exists() 337 && dest.lastModified() >= source.lastModified() ) 338 { 339 continue; 340 } 341 } 342 final File parent = dest.getParentFile(); 343 if( null != parent ) 344 { 345 if( !parent.exists() && !parent.mkdirs() ) 346 { 347 final String message = 348 "Failed to create output directory: " + parent; 349 throw new BuildException( message ); 350 } 351 } 352 writeType( type ); 353 } 354 } 355 return new Counter( size, services, types ); 356 } 357 358 364 private void writeService( final Service service ) 365 throws IOException 366 { 367 final String fqn = service.getReference().getClassname(); 368 final File file = getOutputFileForService( fqn ); 369 final OutputStream outputStream = new FileOutputStream ( file ); 370 try 371 { 372 getServiceWriter().writeService( service, outputStream ); 373 } 374 catch( final Exception e ) 375 { 376 log( "Error writing service to " + file + ". Cause: " + e ); 377 } 378 finally 379 { 380 shutdownStream( outputStream ); 381 } 382 } 383 384 390 private void writeType( final Type type ) 391 throws IOException 392 { 393 final String fqn = type.getInfo().getClassname(); 394 final File file = getOutputFileForClass( fqn ); 395 final OutputStream outputStream = new FileOutputStream ( file ); 396 try 397 { 398 getTypeWriter().writeType( type, outputStream ); 399 } 400 catch( final Exception e ) 401 { 402 log( "Error writing " + file + ". Cause: " + e ); 403 } 404 finally 405 { 406 shutdownStream( outputStream ); 407 } 408 } 409 410 419 private TypeWriter getTypeWriter() 420 { 421 if( SER_TYPE == m_format ) 422 { 423 return SERIAL_WRITER; 424 } 425 else 426 { 427 return XML_WRITER; 428 } 429 } 430 431 432 441 private ServiceWriter getServiceWriter() 442 { 443 if( SER_TYPE == m_format ) 444 { 445 return SERIAL_SERVICE_WRITER; 446 } 447 else 448 { 449 return XML_SERVICE_WRITER; 450 } 451 } 452 453 460 private File getOutputFileForClass( final String classname ) 461 throws IOException 462 { 463 String filename = 464 classname.replace( '.', File.separatorChar ); 465 466 if( SER_TYPE == m_format ) 467 { 468 filename += ".stype"; 469 } 470 else 471 { 472 filename += m_postfix; 473 } 474 return new File ( m_destDir, filename ).getCanonicalFile(); 475 } 476 477 484 private File getOutputFileForService( final String classname ) 485 throws IOException 486 { 487 String filename = 488 classname.replace( '.', File.separatorChar ); 489 490 if( SER_TYPE == m_format ) 491 { 492 filename += ".sservice"; 493 } 494 else 495 { 496 filename += ".xservice"; 497 } 498 return new File ( m_destDir, filename ).getCanonicalFile(); 499 } 500 501 502 507 private void shutdownStream( final OutputStream outputStream ) 508 { 509 if( null != outputStream ) 510 { 511 try 512 { 513 outputStream.close(); 514 } 515 catch( IOException e ) 516 { 517 } 519 } 520 } 521 522 527 protected final File getDestDir() 528 { 529 return m_destDir; 530 } 531 532 536 private class Counter 537 { 538 private int m_services; 539 private int m_types; 540 private int m_count; 541 Counter( int count, int services, int types ) 542 { 543 m_count = count; 544 m_services = services; 545 m_types = types; 546 } 547 protected int getServices() 548 { 549 return m_services; 550 } 551 protected int getTypes() 552 { 553 return m_types; 554 } 555 protected int getCount() 556 { 557 return m_count; 558 } 559 } 560 } 561 | Popular Tags |