
com.gc.iotools.fmt.DetectionStrategy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wazformat Show documentation
Show all versions of wazformat Show documentation
Format identification utilities
The newest version!
package com.gc.iotools.fmt;
/*
* Copyright (c) 2008, 2014 Gabriele Contini. This source code is released
* under the BSD License.
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gc.iotools.fmt.base.Decoder;
import com.gc.iotools.fmt.base.DetectionLibrary;
import com.gc.iotools.fmt.base.FormatEnum;
import com.gc.iotools.fmt.base.FormatId;
import com.gc.iotools.fmt.base.ResettableInputStream;
import com.gc.iotools.fmt.decoders.CompositeDecoder;
import com.gc.iotools.fmt.detect.droid.DroidDetectorImpl;
final class DetectionStrategy {
private class IdentificationResult {
final FormatId[] formats;
final ResettableInputStream resettableIs;
IdentificationResult(final ResettableInputStream resettableIs,
final FormatId[] formats) {
this.resettableIs = resettableIs;
this.formats = formats;
}
}
private static final Logger LOG = LoggerFactory
.getLogger(DroidDetectorImpl.class);
private static FormatId detectFormatStream(
final ResettableInputStream stream,
final DetectionLibrary[] detectors,
final FormatEnum[] enabledFormats) throws IOException {
FormatId detected = new FormatId(FormatEnum.UNKNOWN, null);
final Collection toDetect = new ArrayList(
Arrays.asList(enabledFormats));
if (detectors != null) {
for (int i = 0; (i < detectors.length)
&& FormatEnum.UNKNOWN.equals(detected.format)
&& (toDetect.size() > 0); i++) {
final DetectionLibrary detectionLibrary = detectors[i];
try {
if (isDetectorNeeded(detectionLibrary, toDetect)) {
detected = detectionLibrary.detect(
toDetect.toArray(new FormatEnum[0]), stream);
toDetect.removeAll(Arrays.asList(detectionLibrary
.getDetectedFormats()));
}
} catch (final Exception e) {
LOG.debug("detector [" + detectionLibrary
+ "] threw exception", e);
}
stream.resetToBeginning();
}
}
return detected;
}
private static Map getDecodersMap(
final Decoder[] decoders) {
final Map formatsMap = new HashMap();
if (decoders != null) {
for (final Decoder decoder : decoders) {
formatsMap.put(decoder.getFormat(), decoder);
}
}
return formatsMap;
}
private static boolean isDetectorNeeded(final DetectionLibrary detect,
final Collection toDetect) {
final FormatEnum[] formats = detect.getDetectedFormats();
boolean result = false;
for (int i = 0; (i < formats.length) && (!result); i++) {
result |= toDetect.contains(formats[i]);
}
return result;
}
private final Decoder[] decoders;
private final DetectionLibrary[] detectionLibraries;
private FormatEnum[] enabledFormats;
private final ResettableStreamRASAdapter internalStream;
// recursion disabled by default
private int maxRecursion = 0;
private IdentificationResult result;
public DetectionStrategy(final DetectionLibrary[] detectors,
final Decoder[] decoders, final FormatEnum[] enabledFormats,
final ResettableStreamRASAdapter istream) {
this.internalStream = istream;
this.detectionLibraries = detectors;
this.decoders = decoders;
this.enabledFormats = enabledFormats;
}
private void checkInitialized() throws IOException {
if (this.result == null) {
this.result = identify();
}
}
private Decoder getDecoder(final List formats,
final Map decMap) {
final Decoder decoder;
if (formats.size() > 1) {
final Collection decoderColl = new ArrayList();
for (final FormatId formatId1 : formats) {
final FormatEnum format = formatId1.format;
final Decoder decoder1 = decMap.get(format);
decoderColl.add(decoder1);
}
decoder = new CompositeDecoder(
decoderColl.toArray(new Decoder[0]));
} else {
final FormatEnum format = formats.get(0).format;
decoder = decMap.get(format);
}
return decoder;
}
public FormatId[] getFormats() throws IOException {
checkInitialized();
return this.result.formats;
}
public ResettableInputStream getStream() throws IOException {
checkInitialized();
return this.result.resettableIs;
}
private IdentificationResult identify() throws IOException {
final List formats = new ArrayList();
final Map decMap = getDecodersMap(this.decoders);
FormatId curFormat;
this.internalStream.enable(true);
ResettableInputStream currentStream = this.internalStream;
int recursionLevel = 0;
do {
curFormat = detectFormatStream(currentStream,
this.detectionLibraries, this.enabledFormats);
if ((recursionLevel == 0)
|| !FormatEnum.UNKNOWN.equals(curFormat)) {
formats.add(curFormat);
}
if (!FormatEnum.UNKNOWN.equals(curFormat.format)
&& decMap.containsKey(curFormat.format)) {
final Decoder decoder = getDecoder(formats, decMap);
currentStream = new ResettableStreamWrapper(
this.internalStream, decoder);
}
recursionLevel++;
} while (decMap.containsKey(curFormat.format)
&& (recursionLevel <= this.maxRecursion));
this.internalStream.enable(false);
return new IdentificationResult(currentStream,
formats.toArray(new FormatId[formats.size()]));
}
public void setEnabledFormats(final FormatEnum[] enabledFormats) {
this.enabledFormats = enabledFormats;
this.result = null;
}
public void setMaxRecursion(final int maxRecursion) {
if (this.maxRecursion != maxRecursion) {
this.result = null;
}
this.maxRecursion = maxRecursion;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy