/* * Copyright 1999-2006 University of Chicago * * Licensed 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.dcache.ftp.client; import java.util.List; import java.util.ArrayList; import java.util.StringTokenizer; /** * Represents features supported by server (as returned by FEAT command). * Use the static members of this class to refer to well known feature names. * Example: check if the server supports PARALLEL feature: * <pre> * FeatureList fl = new FeatureList(client.getFeatureList()); * if (fl.contains(FeatureList.PARALLEL)) { * ... * } * </pre> **/ public class FeatureList { /** * RFC 2389 specified the following syntax for FEAT responce * <pre> * feat-response = error-response / no-features / feature-listing * no-features = "211" SP *TCHAR CRLF * feature-listing = "211-" *TCHAR CRLF * 1*( SP feature CRLF ) * "211 End" CRLF * feature = feature-label [ SP feature-parms ] * feature-label = 1*VCHAR * feature-parms = 1*TCHAR * </pre> * Feature class represence each individual feature and contain two fields * required label and optional parms */ public static final class Feature { private final String label; private final String parms; private Feature(String label) { if (label == null) { throw new NullPointerException("label is null"); } this.label = label; this.parms = null; } private Feature(String label, String parms) { if (label == null) { throw new NullPointerException("label is null"); } this.label = label; this.parms = parms; } /** * @return the name */ public String getLabel() { return label; } /** * @return the qualifiers, null if no qualifiers */ public String getParms() { return parms; } @Override public boolean equals(Object obj) { if (!(obj instanceof Feature)) { return false; } Feature aFeature = (Feature) obj; if (!label.equals(aFeature.label)) { return false; } if (parms == null) { return aFeature.parms == null; } return parms.equals(aFeature.parms); } } // well known labels public static final String SIZE = "SIZE"; public static final String MDTM = "MDTM"; public static final String PARALLEL = "PARALLEL"; public static final String ESTO = "ESTO"; public static final String ERET = "ERET"; public static final String SBUF = "SBUF"; public static final String ABUF = "ABUF"; public static final String DCAU = "DCAU"; public static final String PIPE = "PIPE"; public static final String MODEX = "MODEX"; public static final String GETPUT = "GETPUT"; public static final String CKSUM = "CKSUM"; protected final List<Feature> features = new ArrayList(); public FeatureList(String featReplyMsg) { StringTokenizer responseTokenizer = new StringTokenizer(featReplyMsg, System.getProperty("line.separator")); // ignore the first part of the message if (responseTokenizer.hasMoreElements()) { responseTokenizer.nextToken(); } while (responseTokenizer.hasMoreElements()) { String line = (String) responseTokenizer.nextElement(); line = line.trim().toUpperCase(); if (line.startsWith("211 END")) { break; } String[] splitFeature = line.split(" "); if (splitFeature.length == 2) { features.add(new Feature(splitFeature[0], splitFeature[1])); } else { features.add(new Feature(line)); } } } public boolean contains(String label) { if (label == null) { throw new IllegalArgumentException("label is null"); } //split argument using white space. String[] tokens = label.split(" ", 2); if (tokens.length < 1) { throw new IllegalArgumentException("label is empty"); } label = tokens[0].toUpperCase(); String parms = null; if (tokens.length > 1) { parms = tokens[1]; } for (Feature feature : features) { if (feature.getLabel().equals(label)) { if (parms == null) { //if parms are not specified as a part of the argument // string, we compare labels only return true; } else { //if parms are specified, we compare them as well Feature argFeature = new Feature(label, parms); if (argFeature.equals(feature)) { return true; } } } } return false; } /** * Get all features that have label equal to the argument * Note that RFC 2389 does not require a feature with a * given label to appear only once * * @param label * @return List of found features with given label in the same order * as they were given to us by the server */ public List<Feature> getFeature(String label) { if (label == null) { throw new IllegalArgumentException("feature label is null"); } label = label.toUpperCase(); List<Feature> foundFeatures = new ArrayList(); for (Feature feature : features) { if (feature.getLabel().equals(label)) { foundFeatures.add(feature); } } return foundFeatures; } }