/* $Id$ */
/**
* 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.apache.manifoldcf.agents.transformation.forcedmetadata;
import org.apache.manifoldcf.core.interfaces.*;
import org.apache.manifoldcf.agents.interfaces.*;
import java.io.*;
import java.util.*;
/** This class provides unique Reader and other field instances, when requested, based
* on an input RepositoryDocument. It does this by pulling the values of the field into
* a CharacterInput implementation, thus making a temporary file copy. So it is imperative
* that this object is closed when it is no longer needed.
*/
public class FieldDataFactory {
protected final RepositoryDocument sourceDocument;
// Readers (organized by metadata)
protected final Map<String,CharacterInput[]> metadataReaders = new HashMap<String,CharacterInput[]>();
public FieldDataFactory(RepositoryDocument sourceDocument) {
this.sourceDocument = sourceDocument;
}
public void close()
throws ManifoldCFException {
for (String key : metadataReaders.keySet()) {
CharacterInput[] rt = metadataReaders.get(key);
for (CharacterInput r : rt) {
r.discard();
}
}
}
public Object[] getField(String fieldName)
throws IOException, ManifoldCFException {
CharacterInput[] inputs = metadataReaders.get(fieldName);
if (inputs == null) {
// Either never seen the field before, or it's not a Reader
Object[] fieldValues = sourceDocument.getField(fieldName);
if (fieldValues == null)
return fieldValues;
if (fieldValues instanceof Reader[]) {
// Create a copy
CharacterInput[] newValues = new CharacterInput[fieldValues.length];
try {
// Populate newValues
for (int i = 0; i < newValues.length; i++) {
newValues[i] = new TempFileCharacterInput((Reader)fieldValues[i]);
}
metadataReaders.put(fieldName,newValues);
inputs = newValues;
} catch (Throwable e) {
for (CharacterInput r : newValues)
{
if (r != null)
r.discard();
}
if (e instanceof IOException)
throw (IOException)e;
else if (e instanceof RuntimeException)
throw (RuntimeException)e;
else if (e instanceof Error)
throw (Error)e;
else
throw new RuntimeException("Unknown exception type: "+e.getClass().getName()+": "+e.getMessage(),e);
}
} else {
return fieldValues;
}
}
Reader[] newReaders = new Reader[inputs.length];
for (int i = 0; i < inputs.length; i++)
{
inputs[i].doneWithStream();
newReaders[i] = inputs[i].getStream();
}
return newReaders;
}
public String[] getFieldAsStrings(String fieldName)
throws IOException, ManifoldCFException {
CharacterInput[] cilist = metadataReaders.get(fieldName);
if (cilist == null)
return sourceDocument.getFieldAsStrings(fieldName);
// We've created a local array of CharacterInputs from this field. We'll need to convert these
// to strings.
char[] buffer = new char[65536];
String[] rval = new String[cilist.length];
for (int i = 0; i < rval.length; i++) {
CharacterInput ci = cilist[i];
ci.doneWithStream();
Reader r = ci.getStream();
// Read into a buffer
StringBuilder newValue = new StringBuilder();
while (true)
{
int amt = r.read(buffer);
if (amt == -1)
break;
newValue.append(buffer,0,amt);
}
rval[i] = newValue.toString();
}
sourceDocument.addField(fieldName,rval);
metadataReaders.remove(fieldName);
for (CharacterInput ci : cilist) {
ci.discard();
}
return rval;
}
}