Package org.gudy.azureus2.platform.macosx

Source Code of org.gudy.azureus2.platform.macosx.PListEditor

/*
* Created on Apr 1, 2008
* Created by Paul Gardner
*
* Copyright 2008 Vuze, Inc.  All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/

package org.gudy.azureus2.platform.macosx;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import org.gudy.azureus2.core3.util.ByteFormatter;
import org.gudy.azureus2.core3.util.FileUtil;

public class
PListEditor
  private String plistFile;
 
  private boolean  found_bom;
 
  public
  PListEditor(
    String plistFile )
 
    throws IOException
  {
    this.plistFile = plistFile;
   
    File  file  = new File( plistFile );
   
    if ( !file.exists()){
     
      throw( new IOException( "plist file '" + file + "' doesn't exist" ));
    }
   
    if ( !file.canWrite()){
     
      throw( new IOException( "plist file '" + file + "' is read only" ));
    }
  }
 
  public void
  setFileTypeExtensions(
    String[] extensions )
 
    throws IOException
  {
    StringBuffer value = new StringBuffer();
    StringBuffer find = new StringBuffer();
    find.append("(?s).*?<key>CFBundleDocumentTypes</key>\\s*<array>.*?<key>CFBundleTypeExtensions</key>\\s*<array>");
    for(int i = 0 ; i < extensions.length ; i++) {
      value.append("\n\t\t\t\t<string>");
      value.append(extensions[i]);
      value.append("</string>");
     
      find.append(".*?");
      find.append(extensions[i]);
    }
    value.append("\n\t\t\t");
   
    find.append(".*?</array>.*");
    String match = "(?s)(<key>CFBundleDocumentTypes</key>\\s*<array>.*?<key>CFBundleTypeExtensions</key>\\s*<array>)(.*?)(</array>)";
   
    setValue(find.toString(), match, value.toString());
  }
 
  public void
  setSimpleStringValue(
    String key,
    String value)
 
    throws IOException
  {
    String find = "(?s).*?<key>" + key + "</key>\\s*" + "<string>" + value + "</string>.*";
    String match = "(?s)(<key>" + key + "</key>\\s*" + "<string>)(.*?)(</string>)";
    setValue(find, match, value);
  }
 
  public void
  setArrayValues(
    String key,
    String valueType,
    String[] values)
 
    throws IOException
  {
    StringBuffer value = new StringBuffer();
    StringBuffer find = new StringBuffer();
    find.append("(?s).*?<key>" + key + "</key>\\s*" + "<array>");
    for(int i = 0 ; i < values.length ; i++) {
      find.append("\\s*<" + valueType + ">" + values[i] + "</" + valueType + ">");
      value.append("\n\t\t\t\t<" + valueType + ">");
      value.append(values[i]);
      value.append("</" + valueType + ">");
    }
    find.append("\\s*</array>.*");
    value.append("\n\t\t\t");
   
    String match = "(?s)(<key>" + key + "</key>\\s*<array>)(.*?)(</array>)";
   
    setValue(find.toString(),match,value.toString());
  }
 
  private boolean
  isValuePresent(
    String  fileContent,
    String   match )
 
    throws IOException
  {   
    //System.out.println("Searching for:\n" + match);
    return fileContent.matches(match);
  }
 

  /**
   *
   * @param find the regex expression to find if the value is already present
   * @param match the regex expression that will match for the replace, it needs to capture 3 groups, the 2nd one being replaced by value
   * @param value the value that replaces the 2nd match group
   */
  private void
  setValue(
    String find,
    String match,
    String value)
 
    throws IOException
  {
    String fileContent = getFileContent();
   
    if( !isValuePresent(fileContent,find)) {
      //System.out.println("Changing " +plistFile);
      fileContent = fileContent.replaceFirst(match, "$1"+value + "$3");
      setFileContent(fileContent);
      touchFile();
    }
  }
 
  private String
  getFileContent()
    throws IOException
  {
    InputStreamReader reader = null;

    try{
      byte[]  file_bytes = FileUtil.readFileAsByteArray( new File( plistFile ));
     
        // handle UTF-8 encoded BOM EFBBBF
           
      if (   file_bytes.length > 3 &&
          file_bytes[0] == (byte)0xEF &&
          file_bytes[1] == (byte)0xBB &&
          file_bytes[2] == (byte)0xBF ){
       
        found_bom = true;
       
        reader = new InputStreamReader( new ByteArrayInputStream( file_bytes, 3, file_bytes.length - 3 ));
       
      }else{
       
        found_bom = false;
       
        reader = new InputStreamReader( new ByteArrayInputStream( file_bytes ));

      }
         
      //max 32KB
     
      int length = 32 * 1024;
     
      char[] buffer = new char[length];
     
      int offset = 0;
     
      int len = 0;
     
      while((len = reader.read(buffer,offset,length-offset)) > 0) {
        offset += len;
      }
     
      String result =  new String(buffer,0,offset);
     
      return result;
     
    } finally {
      if(reader != null) {
        reader.close();
      }
    }
   
   
    //return FileUtil.readFileAsString(new File(plistFile), 64*1024, "UTF-8" );
  }
 
  private void
  setFileContent(
    String fileContent )
 
    throws IOException
  {
    File  file    = new File( plistFile );
   
    File  backup_file = new File( plistFile + ".bak" );
   
    if ( file.exists()){
     
      if ( !FileUtil.copyFile( file, backup_file )){
       
        throw( new IOException( "Failed to backup plist file prior to modification" ));
      }
    }
   
    boolean  ok = false;
   
    try{
     
      ByteArrayOutputStream  baos = new ByteArrayOutputStream( fileContent.length() + 256 );
     
      if ( found_bom ){
       
          // preserve UTF-8 BOM if it was found
       
        baos.write( new byte[]{ (byte)0xEF, (byte)0xBB, (byte)0xBF });
      }
     
      OutputStreamWriter osw = new OutputStreamWriter( baos );
     
      osw.write( fileContent );
     
      osw.close();
     
      FileOutputStream out = null;
           
      try{
       
        out = new FileOutputStream( plistFile );

          out.writebaos.toByteArray() );
 
      }finally{
       
        if( out != null ){
         
          out.close();
         
          ok = true;
        }
      }
    }finally{
      if ( ok ){
       
        backup_file.delete();
       
      }else{
       
        if ( backup_file.exists()){
         
          File  bork_file = new File( plistFile + ".bad" );

          file.renameTo( bork_file );
         
          file.delete();
         
          backup_file.renameTo( file );
        }
      }
    }
  }
 
  public void
  touchFile()
  {
    File  file  = new File( plistFile );
    for(int i = 0 ; i <= 2 ; i++) {
      if(file != null) {
        String command[] = new String[] { "touch", file.getAbsolutePath() };
       
        try{
          Runtime.getRuntime().exec(command);
         
        } catch(Exception e) {
         
          e.printStackTrace();
        }
      }
      file = file.getParentFile();
    }
  }
 
  public static void main(String args[]) {
    try{
      PListEditor editor = new PListEditor("/Applications/Vuze.app/Contents/Info.plist");
      editor.setFileTypeExtensions(new String[] {"torrent","tor","vuze","vuz"});
      editor.setSimpleStringValue("CFBundleName", "Vuze");
      editor.setSimpleStringValue("CFBundleTypeName", "Vuze Download");
      editor.setSimpleStringValue("CFBundleGetInfoString","Vuze");
      editor.setArrayValues("CFBundleURLSchemes", "string", new String[] {"magnet","dht"});
    }catch( Throwable e ){
     
      e.printStackTrace();
    }
  }

}
TOP

Related Classes of org.gudy.azureus2.platform.macosx.PListEditor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.