org.apache.felix.gogo.command.Files Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.felix.gogo.command Show documentation
Show all versions of org.apache.felix.gogo.command Show documentation
Provides basic shell commands for Gogo.
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.apache.felix.gogo.command;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Descriptor;
import org.osgi.framework.BundleContext;
import static org.apache.felix.gogo.command.Util.CWD;
public class Files
{
@SuppressWarnings("unused")
private final BundleContext m_bc;
public Files(BundleContext bc)
{
m_bc = bc;
}
@Descriptor("get current directory")
public File cd(
@Descriptor("automatically supplied shell session") CommandSession session)
{
try
{
return cd(session, null);
}
catch (IOException ex)
{
throw new RuntimeException("Unable to get current directory");
}
}
@Descriptor("change current directory")
public File cd(
@Descriptor("automatically supplied shell session") CommandSession session,
@Descriptor("target directory") String dir)
throws IOException
{
File cwd = (File) session.get(CWD);
if (cwd == null)
{
cwd = new File(".").getCanonicalFile();
session.put(CWD, cwd);
}
if ((dir == null) || (dir.length() == 0))
{
return cwd;
}
URI curUri = cwd.toURI();
URI newUri = curUri.resolve(dir);
cwd = new File(newUri);
if (!cwd.exists())
{
throw new IOException("Directory does not exist");
}
else if (!cwd.isDirectory())
{
throw new IOException("Target is not a directory");
}
session.put(CWD, cwd.getCanonicalFile());
return cwd;
}
@Descriptor("get current directory contents")
public File[] ls(
@Descriptor("automatically supplied shell session") CommandSession session)
throws IOException
{
return ls(session, null);
}
@Descriptor("get specified path contents")
public File[] ls(
@Descriptor("automatically supplied shell session") CommandSession session,
@Descriptor("path with optionally wildcarded file name") String pattern)
throws IOException
{
pattern = ((pattern == null) || (pattern.length() == 0)) ? "." : pattern;
pattern = ((pattern.charAt(0) != File.separatorChar) && (pattern.charAt(0) != '.'))
? "./" + pattern : pattern;
int idx = pattern.lastIndexOf(File.separatorChar);
String parent = (idx < 0) ? "." : pattern.substring(0, idx + 1);
String target = (idx < 0) ? pattern : pattern.substring(idx + 1);
File actualParent = ((parent.charAt(0) == File.separatorChar)
? new File(parent) : new File(cd(session), parent)).getCanonicalFile();
idx = target.indexOf(File.separatorChar, idx);
boolean isWildcarded = (target.indexOf('*', idx) >= 0);
File[] files;
if (isWildcarded)
{
if (!actualParent.exists())
{
throw new IOException("File does not exist");
}
final List pieces = parseSubstring(target);
files = actualParent.listFiles(new FileFilter() {
public boolean accept(File pathname)
{
return compareSubstring(pieces, pathname.getName());
}
});
}
else
{
File actualTarget = new File(actualParent, target).getCanonicalFile();
if (!actualTarget.exists())
{
throw new IOException("File does not exist");
}
if (actualTarget.isDirectory())
{
files = actualTarget.listFiles();
}
else
{
files = new File[] { actualTarget };
}
}
return files;
}
public static List parseSubstring(String value)
{
List pieces = new ArrayList<>();
StringBuilder ss = new StringBuilder();
// int kind = SIMPLE; // assume until proven otherwise
boolean wasStar = false; // indicates last piece was a star
boolean leftstar = false; // track if the initial piece is a star
boolean rightstar = false; // track if the final piece is a star
int idx = 0;
// We assume (sub)strings can contain leading and trailing blanks
boolean escaped = false;
loop: for (;;)
{
if (idx >= value.length())
{
if (wasStar)
{
// insert last piece as "" to handle trailing star
rightstar = true;
}
else
{
pieces.add(ss.toString());
// accumulate the last piece
// note that in the case of
// (cn=); this might be
// the string "" (!=null)
}
ss.setLength(0);
break loop;
}
// Read the next character and account for escapes.
char c = value.charAt(idx++);
if (!escaped && ((c == '(') || (c == ')')))
{
throw new IllegalArgumentException(
"Illegal value: " + value);
}
else if (!escaped && (c == '*'))
{
if (wasStar)
{
// encountered two successive stars;
// I assume this is illegal
throw new IllegalArgumentException("Invalid filter string: " + value);
}
if (ss.length() > 0)
{
pieces.add(ss.toString()); // accumulate the pieces
// between '*' occurrences
}
ss.setLength(0);
// if this is a leading star, then track it
if (pieces.size() == 0)
{
leftstar = true;
}
wasStar = true;
}
else if (!escaped && (c == '\\'))
{
escaped = true;
}
else
{
escaped = false;
wasStar = false;
ss.append(c);
}
}
if (leftstar || rightstar || pieces.size() > 1)
{
// insert leading and/or trailing "" to anchor ends
if (rightstar)
{
pieces.add("");
}
if (leftstar)
{
pieces.add(0, "");
}
}
return pieces;
}
public static boolean compareSubstring(List pieces, String s)
{
// Walk the pieces to match the string
// There are implicit stars between each piece,
// and the first and last pieces might be "" to anchor the match.
// assert (pieces.length > 1)
// minimal case is *
boolean result = true;
int len = pieces.size();
int index = 0;
loop: for (int i = 0; i < len; i++)
{
String piece = pieces.get(i);
// If this is the first piece, then make sure the
// string starts with it.
if (i == 0)
{
if (!s.startsWith(piece))
{
result = false;
break loop;
}
}
// If this is the last piece, then make sure the
// string ends with it.
if (i == len - 1)
{
result = s.endsWith(piece);
break loop;
}
// If this is neither the first or last piece, then
// make sure the string contains it.
if ((i > 0) && (i < (len - 1)))
{
index = s.indexOf(piece, index);
if (index < 0)
{
result = false;
break loop;
}
}
// Move string index beyond the matching piece.
index += piece.length();
}
return result;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy