org.netbeans.modules.subversion.config.KVFile Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.subversion.config;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import org.netbeans.modules.subversion.Subversion;
import org.netbeans.modules.versioning.util.FileUtils;
/**
* Handles the credential or property files used by Subversion.
*
* @author Tomas Stupka
*
*/
public class KVFile {
/** a Map holding the entries*/
private Map map;
/** a Map holding the keys*/
private Map keyMap;
/** the credential or property file */
private final File file;
/**
* Creates a new instance
*
* @parameter file the credential or property file
*/
public KVFile(File file) {
this.file = file;
try {
if(file.exists()) {
parse();
}
} catch (IOException ex) {
Subversion.LOG.log(Level.INFO, null, ex);
}
}
/**
* Returns the value for the given Key
*
* @param key
* @return the value stored under the given Key
*/
protected byte[] getValue(Key key) {
return (byte[]) getMap().get(key);
}
/**
* Returns the value for the given Key as a String
*
* @param key
* @return the value stored under the given Key as a String
*/
protected String getStringValue(Key key) {
try {
byte[] value = getValue(key);
if (value == null) {
return null;
}
return new String(value, "UTF8");
} catch (UnsupportedEncodingException ex) {
Subversion.LOG.log(Level.SEVERE, null, ex);
return null;
}
}
/**
* Stores the given value under the given Key
*
*/
protected void setValue(Key key, byte[] value) {
getMap().put(key, value);
}
/**
* Returns the Map holding the Key and value pairs
*
* @return map
*/
private Map getMap() {
if(map == null) {
map = new TreeMap();
}
return map;
}
public Map getNormalizedMap() {
Map keyValue = getMap();
Map stringValue = new HashMap(keyValue.size());
Iterator> it = keyValue.entrySet().iterator();
while (it.hasNext()) {
Map.Entry next = it.next();
// getKey().toString() == the normalization
stringValue.put(next.getKey().toString(), (byte[]) next.getValue());
}
return stringValue;
}
/**
* Returns the Map holding the Keys
*
* @return map
*/
private Map getKeyMap() {
if(keyMap == null) {
keyMap = new HashMap();
}
return keyMap;
}
protected Key getKey(Key key) {
Key storedKey = getKey(key.getName());
if(storedKey == null) {
setKey(key);
return key;
}
return storedKey;
}
private Key getKey(String name) {
return getKeyMap().get(name);
}
protected void setKey(Key key) {
getKeyMap().put(key.getName(), key);
}
/**
* Parses the instances file.
*
*/
private void parse() throws IOException {
InputStream is = null;
try {
is = FileUtils.createInputStream(file);
int keyIdx = 0;
while(!checkEOF(is)) {
int keyLength = readEntryLength(is); // key length
byte[] keyName = new byte[keyLength];
is.read(keyName);
is.read(); // skip '\n'
int valueLength = readEntryLength(is); // value length
byte[] value = new byte[valueLength];
is.read(value);
Key key = new Key(keyIdx, new String(keyName, "UTF8"));
setKey(key);
getMap().put(key, value);
is.read(); // skip '\n'
keyIdx++;
}
} catch (EOFException eofe) {
if(getMap().size() > 0) {
// there are already some key-value pairs ->
// something in the file structure seems to be wrong
throw new EOFException(file.getAbsolutePath());
}
// otherwise skip the exception, could be just an empty file
} catch (NumberFormatException nfe) {
throw new IOException(file.getAbsolutePath(), nfe);
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
Subversion.LOG.log(Level.INFO, null, e); // should not happen
}
}
}
private boolean checkEOF(InputStream is) throws IOException {
is.mark(3);
byte[] end = new byte[3];
is.read(end);
is.reset();
if(end[0] == -1 || end[1] == -1 || end[2] == -1) {
throw new EOFException();
}
return end[0] == 'E' && end[1] == 'N' && end[2] == 'D';
}
private int readEntryLength(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte b = (byte) is.read();
while ( b != '\n') {
if(b == -1) {
throw new EOFException();
}
baos.write(b);
b = (byte) is.read();
}
String line = baos.toString();
return Integer.decode(line.substring(2)).intValue();
}
public void store() throws IOException {
store(file);
}
public void store(File file) throws IOException {
OutputStream os = null;
try {
File parent = file.getParentFile();
if(parent!=null && !parent.exists()) {
parent.mkdirs();
}
os = FileUtils.createOutputStream(file);
for (Iterator it = getMap().keySet().iterator(); it.hasNext();) {
Key key = (Key) it.next();
byte[] value = (byte[]) getMap().get(key);
StringBuffer sb = new StringBuffer();
sb.append("K "); // NOI18N
sb.append(key.getName().length());
sb.append("\n"); // NOI18N
sb.append(key.getName());
sb.append("\n"); // NOI18N
sb.append("V "); // NOI18N
sb.append(value.length);
sb.append("\n"); // NOI18N
os.write(sb.toString().getBytes("UTF8"));
os.write(value);
os.write("\n".getBytes()); // NOI18N
}
os.write("END\n".getBytes()); // NOI18N
os.flush();
} finally {
if(os != null) {
try {
os.close();
} catch (IOException ex) {
Subversion.LOG.log(Level.INFO, null, ex);
}
}
}
}
protected File getFile() {
return file;
}
void setValue(Key key, String value) {
setValue(key, value.getBytes());
}
/**
* Represents a key
*/
protected static class Key implements Comparable {
/** the key index */
private final int idx;
/** the keys name */
private final String name;
/** creates a new instance */
protected Key(int idx, String name) {
this.name = name;
this.idx = idx;
}
public int getIndex() {
return idx;
}
public String getName() {
return name;
}
public boolean equals(Object obj) {
if( !(obj instanceof Key) ) {
return false;
}
Key key = (Key) obj;
return key.getIndex() == getIndex() && key.getName().equals(getName());
}
public int hashCode() {
StringBuffer sb = new StringBuffer();
sb.append(getName());
sb.append(getIndex());
return sb.toString().hashCode();
}
public int compareTo(Object obj) {
if( !(obj instanceof Key) ) {
return 0;
}
Key key = (Key) obj;
if (key.getIndex() < getIndex()) {
return 1;
} else if (key.getIndex() > getIndex()) {
return -1;
}
return 0;
}
public String toString() {
return name;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy