Home » xmlbeans-2.5.0-src » repackage » [javadoc | source]

    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   
   16   package repackage;
   17   
   18   import java.io;
   19   import java.util;
   20   import java.util.regex;
   21   
   22   public class Repackage
   23   {
   24       public static void main ( String[] args ) throws Exception
   25       {
   26           new Repackage(args).repackage();
   27       }
   28       
   29       private Repackage(String[] args)
   30       {
   31           String sourceDir = null;
   32           String targetDir = null;
   33           String repackageSpec = null;
   34           boolean failure = false;
   35           
   36           for (int i = 0; i < args.length; i++)
   37           {
   38               if (args[i].equals("-repackage") && i + 1 < args.length)
   39                   repackageSpec = args[++i];
   40               else if (args[i].equals("-f") && i + 1 < args.length)
   41                   sourceDir = args[++i];
   42               else if (args[i].equals("-t") && i + 1 < args.length)
   43                   targetDir = args[++i];
   44               else
   45                   failure = true;
   46           }
   47           
   48           if (failure || repackageSpec == null || (sourceDir == null ^ targetDir == null))
   49               throw new RuntimeException("Usage: repackage -repackage [spec] [ -f [sourcedir] -t [targetdir] ]");
   50           
   51           _repackager = new Repackager(repackageSpec);
   52   
   53           if (sourceDir==null || targetDir==null)
   54               return;
   55   
   56           _sourceBase = new File(sourceDir);
   57           _targetBase = new File(targetDir);
   58       }
   59     
   60       
   61       public void repackage () throws Exception
   62       {
   63           if (_sourceBase==null || _targetBase==null)
   64           {   // read from system.in, write on system.out
   65               System.out.println( _repackager.repackage(readInputStream(System.in)).toString() );
   66               return;
   67           }
   68   
   69           _fromPackages = _repackager.getFromPackages();
   70           _toPackages = _repackager.getToPackages();
   71           
   72           _packagePattern =
   73               Pattern.compile( "^\\s*package\\s+((?:\\w|\\.)*)\\s*;", Pattern.MULTILINE );
   74           
   75           _moveAlongFiles = new ArrayList();
   76           _movedDirs = new HashMap();
   77           
   78   //        System.out.println( "Deleting repackage dir ..." );
   79   //        recursiveDelete( _targetBase );
   80           
   81           _targetBase.mkdirs();
   82           
   83           ArrayList files = new ArrayList();
   84   
   85           fillFiles( files, _sourceBase );
   86           
   87           System.out.println( "Repackaging " + files.size() + " files ..." );
   88   
   89           int prefixLength = _sourceBase.getCanonicalPath().length();
   90   
   91           for ( int i = 0 ; i < files.size() ; i++ )
   92           {
   93               File from = (File) files.get( i );
   94   
   95               String name = from.getCanonicalPath().substring( prefixLength + 1 );
   96   
   97               repackageFile( name );
   98           }
   99           
  100           finishMovingFiles();
  101           
  102           if (_skippedFiles > 0)
  103               System.out.println("Skipped " + _skippedFiles + " unmodified files.");
  104       }
  105       
  106       private boolean fileIsUnchanged(String name)
  107       {
  108           File sourceFile = new File( _sourceBase, name );
  109           File targetFile = new File( _targetBase, name );
  110           return (sourceFile.lastModified() < targetFile.lastModified());
  111       }
  112   
  113       public void repackageFile ( String name )
  114           throws IOException
  115       {
  116           if (name.endsWith( ".java" ))
  117               repackageJavaFile( name );
  118           else if (name.endsWith( ".xsdconfig" ) ||
  119                   name.endsWith( ".xml" ) ||
  120                   name.endsWith( ".g" ) )
  121               repackageNonJavaFile( name );
  122           else if (name.startsWith( "bin" + File.separatorChar ))
  123               repackageNonJavaFile( name );
  124           else
  125               moveAlongWithJavaFiles( name );
  126       }
  127   
  128       public void moveAlongWithJavaFiles( String name )
  129       {
  130           _moveAlongFiles.add(name);
  131       }
  132       
  133       public void finishMovingFiles ( )
  134           throws IOException
  135       {
  136           for ( Iterator i = _moveAlongFiles.iterator(); i.hasNext(); )
  137           {
  138               String name = (String) i.next();
  139               String toName = name;
  140               
  141               String srcDir = Repackager.dirForPath( name );
  142               String toDir = (String) _movedDirs.get( srcDir );
  143               
  144               if (toDir != null)
  145                   toName = new File( toDir, new File( name ).getName() ).toString(); 
  146   
  147               if (name.endsWith( ".html" ))
  148                   repackageNonJavaFile(name, toName);
  149               else
  150                   justMoveNonJavaFile(name, toName);
  151           }
  152       }
  153   
  154       public void repackageNonJavaFile(String name)
  155           throws IOException
  156       {
  157           File sourceFile = new File( _sourceBase, name );
  158           File targetFile = new File( _targetBase, name );
  159           
  160           if (sourceFile.lastModified() < targetFile.lastModified())
  161               _skippedFiles += 1;
  162           else
  163               writeFile( targetFile, _repackager.repackage( readFile( sourceFile ) ) );
  164       }
  165       
  166       public void repackageNonJavaFile ( String sourceName, String targetName )
  167           throws IOException
  168       {
  169           File sourceFile = new File( _sourceBase, sourceName );
  170           File targetFile = new File( _targetBase, targetName );
  171           
  172           if (sourceFile.lastModified() < targetFile.lastModified())
  173               _skippedFiles += 1;
  174           else
  175               writeFile( targetFile, _repackager.repackage( readFile( sourceFile ) ) );
  176       }
  177       
  178       public void justMoveNonJavaFile ( String sourceName, String targetName )
  179           throws IOException
  180       {
  181           File sourceFile = new File( _sourceBase, sourceName );
  182           File targetFile = new File( _targetBase, targetName );
  183           
  184           if (sourceFile.lastModified() < targetFile.lastModified())
  185               _skippedFiles += 1;
  186           else
  187               copyFile( sourceFile, targetFile );
  188       }
  189       
  190       public void repackageJavaFile ( String name )
  191           throws IOException
  192       {
  193           File sourceFile = new File(_sourceBase, name);
  194           StringBuffer sb = readFile(sourceFile);
  195   
  196           Matcher packageMatcher = _packagePattern.matcher( sb );
  197   
  198           if (packageMatcher.find())
  199           {
  200               String pkg = packageMatcher.group( 1 );
  201               int pkgStart = packageMatcher.start( 1 );
  202               int pkgEnd = packageMatcher.end( 1 );
  203               
  204               if (packageMatcher.find())
  205                   throw new RuntimeException( "Two package specifications found: " + name );
  206   
  207               List filePath = Repackager.splitPath( name, File.separatorChar );
  208               String srcDir = Repackager.dirForPath( name );
  209               
  210               // Sort the repackage spec so that longer from's are first to match
  211               // longest package first
  212   
  213               for ( ; ; )
  214               {
  215                   boolean swapped = false;
  216   
  217                   for ( int i = 1 ; i < filePath.size() ; i++ )
  218                   {
  219                       String spec1 = (String) filePath.get( i - 1 );
  220                       String spec2 = (String) filePath.get( i );
  221   
  222                       if (spec1.indexOf( ':' ) < spec2.indexOf( ':' ))
  223                       {
  224                           filePath.set( i - 1, spec2 );
  225                           filePath.set( i, spec1 );
  226   
  227                           swapped = true;
  228                       }
  229                   }
  230   
  231                   if (!swapped)
  232                       break;
  233               }
  234   
  235               List pkgPath = Repackager.splitPath( pkg, '.' );
  236   
  237               int f = filePath.size() - 2;
  238   
  239               if (f<0  ||  (filePath.size()-1)< pkgPath.size())
  240                   throw new RuntimeException("Package spec differs from file path: " + name);
  241   
  242               for ( int i = pkgPath.size() - 1 ; i >= 0 ; i-- )
  243               {
  244                   if (!pkgPath.get( i ).equals( filePath.get( f ) ))
  245                       throw new RuntimeException( "Package spec differs from file path: " + name );
  246                   f--;
  247               }
  248   
  249               List changeTo = null;
  250               List changeFrom = null;
  251               
  252               from:
  253               for ( int i = 0 ; i < _fromPackages.size() ; i ++ )
  254               {
  255                   List from = (List) _fromPackages.get( i );
  256   
  257                   if (from.size() <= pkgPath.size())
  258                   {
  259                       for ( int j = 0 ; j < from.size() ; j++ )
  260                           if (!from.get( j ).equals( pkgPath.get( j )))
  261                               continue from;
  262   
  263                       changeFrom = from;
  264                       changeTo = (List) _toPackages.get( i );
  265   
  266                       break;
  267                   }
  268               }
  269   
  270               if (changeTo != null)
  271               {
  272                   String newPkg = "";
  273                   String newName = "";
  274   
  275                   for ( int i = 0 ; i < changeTo.size() ; i++ )
  276                   {
  277                       if (i > 0)
  278                       {
  279                           newPkg += ".";
  280                           newName += File.separatorChar;
  281                       }
  282                       
  283                       newPkg += changeTo.get( i );
  284                       newName += changeTo.get( i );
  285                   }
  286                   
  287                   for ( int i = filePath.size() - pkgPath.size() - 2 ; i >= 0 ; i-- )
  288                       newName = (String) filePath.get( i ) + File.separatorChar + newName;
  289   
  290                   for ( int i = changeFrom.size() ; i < pkgPath.size() ; i++ )
  291                   {
  292                       newName += File.separatorChar + (String) pkgPath.get( i );
  293                       newPkg += '.' + (String) pkgPath.get( i );
  294                   }
  295   
  296                   newName += File.separatorChar + (String) filePath.get( filePath.size() - 1 );
  297   
  298                   sb.replace( pkgStart, pkgEnd, newPkg );
  299   
  300                   name = newName;
  301                   String newDir = Repackager.dirForPath( name );
  302                   
  303                   if (!srcDir.equals(newDir))
  304                   {
  305                       _movedDirs.put(srcDir, newDir);
  306                   }
  307               }
  308           }
  309           
  310           File targetFile = new File(_targetBase, name); // new name
  311           
  312           if (sourceFile.lastModified() < targetFile.lastModified())
  313           {
  314               _skippedFiles += 1;
  315               return;
  316           }
  317   
  318           writeFile( new File( _targetBase, name ), _repackager.repackage( sb ) );
  319       }
  320   
  321       void writeFile ( File f, StringBuffer chars )
  322           throws IOException
  323       {
  324           f.getParentFile().mkdirs();
  325           
  326           OutputStream out = new FileOutputStream( f );
  327           Writer w = new OutputStreamWriter( out );
  328           Reader r = new StringReader( chars.toString() );
  329   
  330           copy( r, w );
  331   
  332           r.close();
  333           w.close();
  334           out.close();
  335       }
  336       
  337       StringBuffer readFile ( File f )
  338           throws IOException
  339       {
  340           InputStream in = new FileInputStream( f );
  341           Reader r = new InputStreamReader( in );
  342           StringWriter w = new StringWriter();
  343   
  344           copy( r, w );
  345   
  346           w.close();
  347           r.close();
  348           in.close();
  349   
  350           return w.getBuffer();
  351       }
  352   
  353       StringBuffer readInputStream ( InputStream is )
  354           throws IOException
  355       {
  356           Reader r = new InputStreamReader( is );
  357           StringWriter w = new StringWriter();
  358   
  359           copy( r, w );
  360   
  361           w.close();
  362           r.close();
  363   
  364           return w.getBuffer();
  365       }
  366   
  367       public static void copyFile ( File from, File to ) throws IOException
  368       {
  369           to.getParentFile().mkdirs();
  370           
  371           FileInputStream in = new FileInputStream( from );
  372           FileOutputStream out = new FileOutputStream( to );
  373   
  374           copy( in, out );
  375           
  376           out.close();
  377           in.close();
  378       }
  379       
  380       public static void copy ( InputStream in, OutputStream out ) throws IOException
  381       {
  382           byte[] buffer = new byte [ 1024 * 16 ];
  383   
  384           for ( ; ; )
  385           {
  386               int n = in.read( buffer, 0, buffer.length );
  387   
  388               if (n < 0)
  389                   break;
  390   
  391               out.write( buffer, 0, n );
  392           }
  393       }
  394       
  395       public static void copy ( Reader r, Writer w ) throws IOException
  396       {
  397           char[] buffer = new char [ 1024 * 16 ];
  398   
  399           for ( ; ; )
  400           {
  401               int n = r.read( buffer, 0, buffer.length );
  402   
  403               if (n < 0)
  404                   break;
  405   
  406               w.write( buffer, 0, n );
  407           }
  408       }
  409       
  410       public void fillFiles ( ArrayList files, File file ) throws IOException
  411       {
  412           if (!file.isDirectory())
  413           {
  414               files.add( file );
  415               return;
  416           }
  417   
  418           // Exclude the build directory
  419   
  420           if (file.getName().equals( "build" ))
  421               return;
  422           
  423           // Exclude CVS directories
  424           if (file.getName().equals( "CVS" ))
  425               return;
  426   
  427           String[] entries = file.list();
  428   
  429           for ( int i = 0 ; i < entries.length ; i++ )
  430               fillFiles( files, new File( file, entries[ i ] ) );
  431       }
  432   
  433       public void recursiveDelete ( File file ) throws IOException
  434       {
  435           if (!file.exists())
  436               return;
  437   
  438           if (file.isDirectory())
  439           {
  440               String[] entries = file.list();
  441   
  442               for ( int i = 0 ; i < entries.length ; i++ )
  443                   recursiveDelete( new File( file, entries[ i ] ) );
  444           }
  445   
  446           file.delete();
  447       }
  448   
  449       private File _sourceBase;
  450       private File _targetBase;
  451   
  452       private List _fromPackages;
  453       private List _toPackages;
  454       
  455       private Pattern _packagePattern;
  456   
  457       private Repackager _repackager;
  458       
  459       private Map _movedDirs;
  460       private List _moveAlongFiles;
  461       private int _skippedFiles;
  462   }

Home » xmlbeans-2.5.0-src » repackage » [javadoc | source]