commons-net.jar Source Code

commons-net.jar is the bytecode of Apache Commons Net library, which implements the client side of many basic Internet protocols.

Apache Commons Net Source Code files are provided in the binary packge (commons-net-3.8.0-bin.zip). You can download it at Apache Commons Net Website.

The source code of commons-net-3.8.0.jar is provided below:

✍: FYIcenter

org/apache/commons/net/ftp/parser/MLSxEntryParser.java

/*
 * 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.commons.net.ftp.parser;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;

import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPFileEntryParserImpl;

/**
 * Parser class for MSLT and MLSD replies. See RFC 3659.
 * <p>
 * Format is as follows:
 * </p>
 * <pre>
 * entry            = [ facts ] SP pathname
 * facts            = 1*( fact ";" )
 * fact             = factname "=" value
 * factname         = "Size" / "Modify" / "Create" /
 *                    "Type" / "Unique" / "Perm" /
 *                    "Lang" / "Media-Type" / "CharSet" /
 * os-depend-fact / local-fact
 * os-depend-fact   = {IANA assigned OS name} "." token
 * local-fact       = "X." token
 * value            = *SCHAR
 *
 * Sample os-depend-fact:
 * UNIX.group=0;UNIX.mode=0755;UNIX.owner=0;
 * </pre>
 * <p>
 * A single control response entry (MLST) is returned with a leading space;
 * multiple (data) entries are returned without any leading spaces.
 * The parser requires that the leading space from the MLST entry is removed.
 * MLSD entries can begin with a single space if there are no facts.
 * </p>
 *
 * @since 3.0
 */
public class MLSxEntryParser extends FTPFileEntryParserImpl
{
    // This class is immutable, so a single instance can be shared.
    private static final MLSxEntryParser INSTANCE = new MLSxEntryParser();

    private static final HashMap<String, Integer> TYPE_TO_INT = new HashMap<>();
    static {
        TYPE_TO_INT.put("file", Integer.valueOf(FTPFile.FILE_TYPE));
        TYPE_TO_INT.put("cdir", Integer.valueOf(FTPFile.DIRECTORY_TYPE)); // listed directory
        TYPE_TO_INT.put("pdir", Integer.valueOf(FTPFile.DIRECTORY_TYPE)); // a parent dir
        TYPE_TO_INT.put("dir", Integer.valueOf(FTPFile.DIRECTORY_TYPE)); // dir or sub-dir
    }

    private static final int[] UNIX_GROUPS = { // Groups in order of mode digits
        FTPFile.USER_ACCESS,
        FTPFile.GROUP_ACCESS,
        FTPFile.WORLD_ACCESS,
    };

    private static final int[][] UNIX_PERMS = { // perm bits, broken down by octal int value
/* 0 */  {},
/* 1 */  {FTPFile.EXECUTE_PERMISSION},
/* 2 */  {FTPFile.WRITE_PERMISSION},
/* 3 */  {FTPFile.EXECUTE_PERMISSION, FTPFile.WRITE_PERMISSION},
/* 4 */  {FTPFile.READ_PERMISSION},
/* 5 */  {FTPFile.READ_PERMISSION, FTPFile.EXECUTE_PERMISSION},
/* 6 */  {FTPFile.READ_PERMISSION, FTPFile.WRITE_PERMISSION},
/* 7 */  {FTPFile.READ_PERMISSION, FTPFile.WRITE_PERMISSION, FTPFile.EXECUTE_PERMISSION},
    };

    /**
     * Create the parser for MSLT and MSLD listing entries
     * This class is immutable, so one can use {@link #getInstance()} instead.
     */
    public MLSxEntryParser()
    {
    }

    @Override
    public FTPFile parseFTPEntry(final String entry) {
        if (entry.startsWith(" ")) {// leading space means no facts are present
            if (entry.length() > 1) { // is there a path name?
                final FTPFile file = new FTPFile();
                file.setRawListing(entry);
                file.setName(entry.substring(1));
                return file;
            }
            return null; // Invalid - no pathname

        }
        final String parts[] = entry.split(" ",2); // Path may contain space
        if (parts.length != 2 || parts[1].isEmpty()) {
            return null; // no space found or no file name
        }
        final String factList = parts[0];
        if (!factList.endsWith(";")) {
            return null;
        }
        final FTPFile file = new FTPFile();
        file.setRawListing(entry);
        file.setName(parts[1]);
        final String[] facts = factList.split(";");
        final boolean hasUnixMode = parts[0].toLowerCase(Locale.ENGLISH).contains("unix.mode=");
        for(final String fact : facts) {
            final String []factparts = fact.split("=", -1); // Don't drop empty values
// Sample missing permission
// drwx------   2 mirror   mirror       4096 Mar 13  2010 subversion
// modify=20100313224553;perm=;type=dir;unique=811U282598;UNIX.group=500;UNIX.mode=0700;UNIX.owner=500; subversion
            if (factparts.length != 2) {
                return null; // invalid - there was no "=" sign
            }
            final String factname = factparts[0].toLowerCase(Locale.ENGLISH);
            final String factvalue = factparts[1];
            if (factvalue.isEmpty()) {
                continue; // nothing to see here
            }
            final String valueLowerCase = factvalue.toLowerCase(Locale.ENGLISH);
            if ("size".equals(factname) || "sizd".equals(factname)) {
                file.setSize(Long.parseLong(factvalue));
            }
            else if ("modify".equals(factname)) {
                final Calendar parsed = parseGMTdateTime(factvalue);
                if (parsed == null) {
                    return null;
                }
                file.setTimestamp(parsed);
            }
            else if ("type".equals(factname)) {
                    final Integer intType = TYPE_TO_INT.get(valueLowerCase);
                    if (intType == null) {
                        file.setType(FTPFile.UNKNOWN_TYPE);
                    } else {
                        file.setType(intType.intValue());
                    }
            }
            else if (factname.startsWith("unix.")) {
                final String unixfact = factname.substring("unix.".length()).toLowerCase(Locale.ENGLISH);
                if ("group".equals(unixfact)){
                    file.setGroup(factvalue);
                } else if ("owner".equals(unixfact)){
                    file.setUser(factvalue);
                } else if ("mode".equals(unixfact)){ // e.g. 0[1]755
                    final int off = factvalue.length()-3; // only parse last 3 digits
                    for(int i=0; i < 3; i++){
                        final int ch = factvalue.charAt(off+i)-'0';
                        if (ch >= 0 && ch <= 7) { // Check it's valid octal
                            for(final int p : UNIX_PERMS[ch]) {
                                file.setPermission(UNIX_GROUPS[i], p, true);
                            }
                        } else {
                            // TODO should this cause failure, or can it be reported somehow?
                        }
                    } // digits
                } // mode
            } // unix.
            else if (!hasUnixMode && "perm".equals(factname)) { // skip if we have the UNIX.mode
                doUnixPerms(file, valueLowerCase);
            } // process "perm"
        } // each fact
        return file;
    }

    /**
     * Parse a GMT time stamp of the form YYYYMMDDHHMMSS[.sss]
     *
     * @param timestamp the date-time to parse
     * @return a Calendar entry, may be {@code null}
     * @since 3.4
     */
    public static Calendar parseGMTdateTime(final String timestamp) {
        final SimpleDateFormat sdf;
        final boolean hasMillis;
        if (timestamp.contains(".")){
            sdf = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
            hasMillis = true;
        } else {
            sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            hasMillis = false;
        }
        final TimeZone GMT = TimeZone.getTimeZone("GMT");
        // both time zones need to be set for the parse to work OK
        sdf.setTimeZone(GMT);
        final GregorianCalendar gc = new GregorianCalendar(GMT);
        final ParsePosition pos = new ParsePosition(0);
        sdf.setLenient(false); // We want to parse the whole string
        final Date parsed = sdf.parse(timestamp, pos);
        if (pos.getIndex()  != timestamp.length()) {
            return null; // did not fully parse the input
        }
        gc.setTime(parsed);
        if (!hasMillis) {
            gc.clear(Calendar.MILLISECOND); // flag up missing ms units
        }
        return gc;
    }

    //              perm-fact    = "Perm" "=" *pvals
    //              pvals        = "a" / "c" / "d" / "e" / "f" /
    //                             "l" / "m" / "p" / "r" / "w"
    private void doUnixPerms(final FTPFile file, final String valueLowerCase) {
        for(final char c : valueLowerCase.toCharArray()) {
            // TODO these are mostly just guesses at present
            switch (c) {
                case 'a':     // (file) may APPEnd
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
                    break;
                case 'c':     // (dir) files may be created in the dir
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
                    break;
                case 'd':     // deletable
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
                    break;
                case 'e':     // (dir) can change to this dir
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION, true);
                    break;
                case 'f':     // (file) renamable
                    // ?? file.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
                    break;
                case 'l':     // (dir) can be listed
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION, true);
                    break;
                case 'm':     // (dir) can create directory here
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
                    break;
                case 'p':     // (dir) entries may be deleted
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
                    break;
                case 'r':     // (files) file may be RETRieved
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION, true);
                    break;
                case 'w':     // (files) file may be STORed
                    file.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
                    break;
                default:
                    break;
                    // ignore unexpected flag for now.
            } // switch
        } // each char
    }

    public static FTPFile parseEntry(final String entry) {
        return INSTANCE.parseFTPEntry(entry);
    }

    public static  MLSxEntryParser getInstance() {
        return INSTANCE;
    }
}

org/apache/commons/net/ftp/parser/MLSxEntryParser.java

 

Or download all of them as a single archive file:

File name: commons-net-3.8.0-sources.jar
File size: 437325 bytes
Release date: 2020-01-22
Download 

 

Download and Install commons-net.jar Binary Package

What Is commons-net.jar

Downloading and Reviewing commons-net.jar

⇑⇑ FAQ for Apache commons-net.jar

2009-02-08, 133251👍, 0💬