/*
* ====================================================================
* Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.internal.wc;
import java.util.ArrayList;
import java.util.Collections;
import org.tmatesoft.svn.core.internal.util.SVNHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @version 1.0
* @author TMate Software Ltd.
*/
public abstract class SVNPasswordCipher {
public static final String SIMPLE_CIPHER_TYPE = "simple";
public static final String WINCRYPT_CIPHER_TYPE = "wincrypt";
private static final SVNPasswordCipher EMPTY_CIPHER = new CompositePasswordCipher(Collections.EMPTY_LIST, SIMPLE_CIPHER_TYPE);
private static final SVNPasswordCipher SIMPLE_CIPHER = new CompositePasswordCipher(Collections.EMPTY_LIST, SIMPLE_CIPHER_TYPE);
private static final SVNPasswordCipher WINCRYPT_CIPHER = new SVNWinCryptPasswordCipher();
private static Map ourInstances = new SVNHashMap();
private static String ourDefaultType = SIMPLE_CIPHER_TYPE;
static {
ourInstances.put(SIMPLE_CIPHER_TYPE, SIMPLE_CIPHER);
if (SVNWinCryptPasswordCipher.isEnabled()) {
ourInstances.put(WINCRYPT_CIPHER_TYPE, WINCRYPT_CIPHER);
ourDefaultType = WINCRYPT_CIPHER_TYPE;
}
}
public static SVNPasswordCipher getInstance(String type) {
if (type == null) {
return EMPTY_CIPHER;
}
synchronized (ourInstances) {
if (ourInstances.containsKey(type)) {
return (SVNPasswordCipher) ourInstances.get(type);
}
}
return EMPTY_CIPHER;
}
public static boolean hasCipher(String type) {
synchronized (ourInstances) {
return type != null && ourInstances.containsKey(type);
}
}
public static void setDefaultCipherType(String type) {
synchronized (ourInstances) {
ourDefaultType = type;
}
}
public static String getDefaultCipherType() {
synchronized (ourInstances) {
if (ourDefaultType != null) {
return ourDefaultType;
} else if (!ourInstances.isEmpty()) {
ourDefaultType = (String) ourInstances.keySet().iterator().next();
return ourDefaultType;
}
}
return SIMPLE_CIPHER_TYPE;
}
public static void registerCipher(String type, SVNPasswordCipher cipher) {
if (type != null && cipher != null) {
synchronized (ourInstances) {
if (ourInstances.containsKey(type)) {
((CompositePasswordCipher) ourInstances.get(type)).addCipher(cipher);
} else {
cipher = new CompositePasswordCipher(cipher);
ourInstances.put(type, cipher);
}
}
}
}
protected SVNPasswordCipher() {
}
public abstract char[] encrypt(char[] rawData);
public abstract char[] decrypt(char[] encyrptedData);
public abstract String getCipherType();
private static class CompositePasswordCipher extends SVNPasswordCipher {
private List myCiphers;
private String myCipherType;
private CompositePasswordCipher(List chiphers, String cipherType) {
myCiphers = chiphers;
myCipherType = cipherType;
}
public CompositePasswordCipher(SVNPasswordCipher chipher) {
myCiphers = new ArrayList();
myCiphers.add(chipher);
}
public synchronized void addCipher(SVNPasswordCipher chipher) {
myCiphers.add(chipher);
}
public synchronized char[] decrypt(char[] encryptedData) {
for (Iterator chiphers = myCiphers.iterator(); chiphers.hasNext();) {
SVNPasswordCipher chipher = (SVNPasswordCipher) chiphers.next();
encryptedData = chipher.decrypt(encryptedData);
}
return encryptedData;
}
public synchronized char[] encrypt(char[] rawData) {
for (Iterator chiphers = myCiphers.iterator(); chiphers.hasNext();) {
SVNPasswordCipher chipher = (SVNPasswordCipher) chiphers.next();
rawData = chipher.encrypt(rawData);
}
return rawData;
}
public String getCipherType() {
return myCipherType;
}
}
}