Package org.gudy.azureus2.core3.internat

Source Code of org.gudy.azureus2.core3.internat.LocaleTorrentUtil

/*
* Created on May 30, 2006 7:32:56 PM
* Copyright (C) 2006 Aelitis, 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; either version 2
* of the License, or (at your option) any later version.
* 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.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*/
package org.gudy.azureus2.core3.internat;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.*;

import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.torrent.TOTorrentException;
import org.gudy.azureus2.core3.torrent.TOTorrentFile;
import org.gudy.azureus2.core3.util.Constants;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.TorrentUtils;

/**
* Locale functions specific to Torrents.

* @note Moved from LocaleUtil to keep (cyclical) dependencies down.
*/
public class LocaleTorrentUtil
{
  private static List listeners = new ArrayList();

  /**
   * Retrieves the encoding of the torrent if it can be determined.
   * <br>
   * Does not prompt the user with choices.
   *
   * @param torrent Torrent to get encoding of
   * @return Locale torrent is in
   *
   * @throws TOTorrentException
   * @throws UnsupportedEncodingException
   */
  static public LocaleUtilDecoder getTorrentEncodingIfAvailable(
      TOTorrent torrent)

    throws TOTorrentException, UnsupportedEncodingException
  {
    String encoding = torrent.getAdditionalStringProperty("encoding");
   
    if (encoding == null) {
      return null;
    }
    if (TOTorrent.ENCODING_ACTUALLY_UTF8_KEYS.equals(encoding)) {
      encoding = "utf8";
    }

    // get canonical name

    String canonical_name;

    try {
      canonical_name = Charset.forName(encoding).name();

    } catch (Throwable e) {

      canonical_name = encoding;
    }

    LocaleUtilDecoder chosenDecoder = null;
    LocaleUtilDecoder[] all_decoders = LocaleUtil.getSingleton().getDecoders();

    for (int i = 0; i < all_decoders.length; i++) {
      if (all_decoders[i].getName().equals(canonical_name)) {
        chosenDecoder = all_decoders[i];
        break;
      }
    }
   
    return chosenDecoder;
  }

  /**
   * Get the torrent's encoding, prompting the user to choose from a list
   * if needed.
   *
   * @param torrent Torrent to get encoding of
   * @return LocaleUtilDecoder that the torrent is in
   *
   * @throws TOTorrentException
   * @throws UnsupportedEncodingException
   *
   */
  // TODO: Use getTorrentEncodingIfAvailable instead of almost-similar code
  //        (merge anything cool from this function's dup code into
  //         getTorrentEncodingIfAvailable)
  static public LocaleUtilDecoder getTorrentEncoding(TOTorrent torrent)

    throws TOTorrentException, UnsupportedEncodingException
  {
    return getTorrentEncoding(torrent, true);
  }
 
  static public LocaleUtilDecoder getTorrentEncoding(TOTorrent torrent, boolean saveToFileAllowed)

  throws TOTorrentException, UnsupportedEncodingException
  {
    String encoding = torrent.getAdditionalStringProperty("encoding");
    if (TOTorrent.ENCODING_ACTUALLY_UTF8_KEYS.equals(encoding)) {
      encoding = "utf8";
    }

    // we can only persist the torrent if it has a filename defined for it

    boolean bSaveToFile;

    try {
      TorrentUtils.getTorrentFileName(torrent);

      bSaveToFile = true;

    } catch (Throwable e) {

      bSaveToFile = false;
    }

    if (encoding != null) {

      // get canonical name

      try {
        LocaleUtilDecoder[] all_decoders = LocaleUtil.getSingleton().getDecoders();
        LocaleUtilDecoder fallback_decoder = LocaleUtil.getSingleton().getFallBackDecoder();

        String canonical_name = encoding.equals(fallback_decoder.getName())
            ? encoding : Charset.forName(encoding).name();

        for (int i = 0; i < all_decoders.length; i++) {

          if (all_decoders[i].getName().equals(canonical_name)) {

            return (all_decoders[i]);
          }
        }
      } catch (Throwable e) {

        Debug.printStackTrace(e);
      }
    }

    // get the decoders valid for various localisable parts of torrent content
    // not in any particular order

    LocaleUtilDecoderCandidate[] candidates = getTorrentCandidates(torrent);

    boolean system_decoder_is_valid = false;

    LocaleUtil localeUtil = LocaleUtil.getSingleton();
    LocaleUtilDecoder system_decoder = localeUtil.getSystemDecoder();
    for (int i = 0; i < candidates.length; i++) {
      if (candidates[i].getDecoder() == system_decoder) {
        system_decoder_is_valid = true;
        break;
      }
    }

    LocaleUtilDecoder selected_decoder = null;

    for (int i = 0; i < listeners.size(); i++) {

      LocaleUtilDecoderCandidate candidate = null;
      try {
        candidate = ((LocaleUtilListener) listeners.get(i)).selectDecoder(
            localeUtil, torrent, candidates);
      } catch (LocaleUtilEncodingException e) {
      }

      if (candidate != null) {

        selected_decoder = candidate.getDecoder();

        break;
      }

      bSaveToFile = false;
    }

    if (selected_decoder == null) {

      // go for system decoder, if valid, fallback if not

      if (system_decoder_is_valid) {

        selected_decoder = localeUtil.getSystemDecoder();

      } else {

        selected_decoder = localeUtil.getFallBackDecoder();
      }
    }

    torrent.setAdditionalStringProperty("encoding", selected_decoder.getName());

    if (bSaveToFile && saveToFileAllowed) {
      TorrentUtils.writeToFile(torrent);
    }

    return (selected_decoder);
  }

  /**
   * Checks the Torrent's text fields (path, comment, etc) against a list
   * of locals, returning only those that can handle all the fields.
   *
   * @param torrent
   * @return
   * @throws TOTorrentException
   * @throws UnsupportedEncodingException
   */
  static protected LocaleUtilDecoderCandidate[] getTorrentCandidates(
      TOTorrent torrent)

    throws TOTorrentException, UnsupportedEncodingException
  {
    long lMinCandidates;
    byte[] minCandidatesArray;

    Set cand_set = new HashSet();
    LocaleUtil localeUtil = LocaleUtil.getSingleton();

    List candidateDecoders = localeUtil.getCandidateDecoders(torrent.getName());
    lMinCandidates = candidateDecoders.size();
    minCandidatesArray = torrent.getName();

    cand_set.addAll(candidateDecoders);

    TOTorrentFile[] files = torrent.getFiles();

    for (int i = 0; i < files.length; i++) {

      TOTorrentFile file = files[i];

      byte[][] comps = file.getPathComponents();

      for (int j = 0; j < comps.length; j++) {
        candidateDecoders = localeUtil.getCandidateDecoders(comps[j]);
        if (candidateDecoders.size() < lMinCandidates) {
          lMinCandidates = candidateDecoders.size();
          minCandidatesArray = comps[j];
        }
        cand_set.retainAll(candidateDecoders);
      }
    }

    byte[] comment = torrent.getComment();

    if (comment != null) {
      candidateDecoders = localeUtil.getCandidateDecoders(comment);
      if (candidateDecoders.size() < lMinCandidates) {
        lMinCandidates = candidateDecoders.size();
        minCandidatesArray = comment;
      }
      cand_set.retainAll(candidateDecoders);
    }

    byte[] created = torrent.getCreatedBy();

    if (created != null) {
      candidateDecoders = localeUtil.getCandidateDecoders(created);
      if (candidateDecoders.size() < lMinCandidates) {
        lMinCandidates = candidateDecoders.size();
        minCandidatesArray = created;
      }
      cand_set.retainAll(candidateDecoders);
    }

    List candidatesList = localeUtil.getCandidatesAsList(minCandidatesArray);
    LocaleUtilDecoderCandidate[] candidates;
    candidates = new LocaleUtilDecoderCandidate[candidatesList.size()];
    candidatesList.toArray(candidates);

    Arrays.sort(candidates, new Comparator() {
      public int compare(Object o1, Object o2) {
        LocaleUtilDecoderCandidate luc1 = (LocaleUtilDecoderCandidate) o1;
        LocaleUtilDecoderCandidate luc2 = (LocaleUtilDecoderCandidate) o2;

        return (luc1.getDecoder().getIndex() - luc2.getDecoder().getIndex());
      }
    });

    return candidates;
  }

  static public void setTorrentEncoding(TOTorrent torrent, String encoding)

    throws LocaleUtilEncodingException
  {
    try {
      LocaleUtil localeUtil = LocaleUtil.getSingleton();
      LocaleUtilDecoderCandidate[] candidates = getTorrentCandidates(torrent);

      String canonical_requested_name;

      // "System" means use the system encoding

      if (encoding.equalsIgnoreCase("system")) {

        canonical_requested_name = localeUtil.getSystemEncoding();

      } else if (encoding.equalsIgnoreCase(LocaleUtilDecoderFallback.NAME)) {

        canonical_requested_name = LocaleUtilDecoderFallback.NAME;

      } else {

        CharsetDecoder requested_decoder = Charset.forName(encoding).newDecoder();

        canonical_requested_name = requested_decoder.charset().name();
      }

      boolean ok = false;

      for (int i = 0; i < candidates.length; i++) {

        if (candidates[i].getDecoder().getName().equals(
            canonical_requested_name)) {

          ok = true;

          break;
        }
      }

      if (!ok) {

        String[] charsets = new String[candidates.length];
        String[] names = new String[candidates.length];

        for (int i = 0; i < candidates.length; i++) {

          LocaleUtilDecoder decoder = candidates[i].getDecoder();

          charsets[i] = decoder.getName();
          names[i] = decoder.decodeString(torrent.getName());
        }

        throw (new LocaleUtilEncodingException(charsets, names));
      }

      torrent.setAdditionalStringProperty("encoding", canonical_requested_name);

    } catch (Throwable e) {

      if (e instanceof LocaleUtilEncodingException) {

        throw ((LocaleUtilEncodingException) e);
      }

      throw (new LocaleUtilEncodingException(e));
    }
  }

  static public void setDefaultTorrentEncoding(TOTorrent torrent)

    throws LocaleUtilEncodingException
  {
    setTorrentEncoding(torrent, Constants.DEFAULT_ENCODING);
  }

  static public String getCurrentTorrentEncoding(TOTorrent torrent) {
    return (torrent.getAdditionalStringProperty("encoding"));
  }

  public static void addListener(LocaleUtilListener l) {
    listeners.add(l);
  }

  public static void removeListener(LocaleUtilListener l) {
    listeners.remove(l);
  }

}
TOP

Related Classes of org.gudy.azureus2.core3.internat.LocaleTorrentUtil

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.