You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2015/11/17 08:10:54 UTC
[2/6] mina-sshd git commit: Moved StandardEnvironment to its own file
Moved StandardEnvironment to its own file
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/512cbd99
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/512cbd99
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/512cbd99
Branch: refs/heads/master
Commit: 512cbd99b684008e28769bd445601f4ffcbbd772
Parents: 77e1123
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Tue Nov 17 09:07:02 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Tue Nov 17 09:07:02 2015 +0200
----------------------------------------------------------------------
.../org/apache/sshd/server/Environment.java | 33 ++--
.../java/org/apache/sshd/server/Signal.java | 66 ++++++--
.../apache/sshd/server/StandardEnvironment.java | 157 +++++++++++++++++++
3 files changed, 230 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/512cbd99/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/Environment.java b/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
index 6449f34..192cb86 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
@@ -34,18 +34,21 @@ public interface Environment {
* Key for the user environment variable
*/
String ENV_USER = "USER";
+
/**
* Key for the lines environment variable. Specifies the number of
- * lines visible on the client side. {@link Environment#ENV_LINES} and
- * {@link Environment#ENV_COLUMNS} make up the console screen size.
+ * lines visible on the client side. {@link #ENV_LINES} and
+ * {@link #ENV_COLUMNS} make up the console screen size.
*/
String ENV_LINES = "LINES";
+
/**
* Key for the columns environment variable. Specifies the number of
- * columns visible on the client side. {@link Environment#ENV_LINES} and
- * {@link Environment#ENV_COLUMNS} make up the console screen size.
+ * columns visible on the client side. {@link #ENV_LINES} and
+ * {@link #ENV_COLUMNS} make up the console screen size.
*/
String ENV_COLUMNS = "COLUMNS";
+
/**
* Key for the term environment variable. Describes the terminal or
* terminal emulation which is in use.
@@ -55,44 +58,44 @@ public interface Environment {
/**
* Retrieve the environment map
*
- * @return the environment map
+ * @return the environment {@link Map} - never {@code null}
*/
Map<String, String> getEnv();
/**
- * Retrieve the pty modes
+ * Retrieve the PTY modes settings
*
- * @return the map of pty modes
+ * @return the {@link Map} of {@link PtyMode}s - never {@code null}
*/
Map<PtyMode, Integer> getPtyModes();
/**
- * Add a qualified listener for the specific signal
+ * Add a qualified listener for the specific signals
*
- * @param listener the listener to register
- * @param signal the signal the listener is interested in
+ * @param listener the {@link SignalListener} to register
+ * @param signal the {@link Signal}s the listener is interested in
*/
void addSignalListener(SignalListener listener, Signal... signal);
/**
- * Add a qualified listener for the specific set of signal
+ * Add a qualified listener for the specific signals
*
- * @param listener the listener to register
- * @param signals the signals the listener is interested in
+ * @param listener the {@link SignalListener} to register
+ * @param signals the {@link Signal}s the listener is interested in
*/
void addSignalListener(SignalListener listener, Collection<Signal> signals);
/**
* Add a global listener for all signals
*
- * @param listener the listener to register
+ * @param listener the {@link SignalListener} to register
*/
void addSignalListener(SignalListener listener);
/**
* Remove a previously registered listener for all the signals it was registered
*
- * @param listener the listener to remove
+ * @param listener the {@link SignalListener} to remove
*/
void removeSignalListener(SignalListener listener);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/512cbd99/sshd-core/src/main/java/org/apache/sshd/server/Signal.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/Signal.java b/sshd-core/src/main/java/org/apache/sshd/server/Signal.java
index 3cb3efb..3d88580 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/Signal.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/Signal.java
@@ -23,6 +23,9 @@ import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.sshd.common.util.GenericUtils;
/**
* System signals definition that the shell can receive.
@@ -63,11 +66,40 @@ public enum Signal {
PWR(30);
/**
- * A {@link Set} of all the available {@link Signal}s
+ * An un-modifiable {@link Set} of all the available {@link Signal}s
*/
public static final Set<Signal> SIGNALS = Collections.unmodifiableSet(EnumSet.allOf(Signal.class));
- private static final Map<String, Signal> LOOKUP_TABLE = new HashMap<String, Signal>(40);
+ /**
+ * An un-modifiable <U>case-insensitive</U> {@link Map} of the names of all available {@link Signal}s
+ * @see #SIGNALS
+ */
+ public static final Map<String, Signal> NAME_LOOKUP_TABLE =
+ Collections.unmodifiableMap(new TreeMap<String, Signal>(String.CASE_INSENSITIVE_ORDER) {
+ private static final long serialVersionUID = 1L; // we're not serializing it
+
+ {
+ for (Signal s : SIGNALS) {
+ put(s.name(), s);
+ }
+ }
+ });
+
+ /**
+ * An un-modifiable {@link Map} of the numeric values of all available {@link Signal}s
+ * @see #SIGNALS
+ * @see #getNumeric()
+ */
+ public static final Map<Integer, Signal> NUMERIC_LOOKUP_TABLE =
+ Collections.unmodifiableMap(new HashMap<Integer, Signal>(SIGNALS.size()) {
+ private static final long serialVersionUID = 1L; // we're not serializing it
+
+ {
+ for (Signal s : SIGNALS) {
+ put(Integer.valueOf(s.getNumeric()), s);
+ }
+ }
+ });
private final int numeric;
@@ -75,19 +107,31 @@ public enum Signal {
this.numeric = numeric;
}
- static {
- // registering the signals in the lookup table to allow faster
- // string based signal lookups
- for (Signal s : Signal.values()) {
- LOOKUP_TABLE.put(s.name(), s);
- }
+ /**
+ * @return The signal's numeric value
+ */
+ public int getNumeric() {
+ return numeric;
}
+ /**
+ * Retrieves a signal value given its name
+ *
+ * @param name The signal's name (case <U>insensitive</U>) - ignored if {@code null}/empty
+ * @return The matching {@link Signal} or {@code null} if no match found
+ */
public static Signal get(String name) {
- return LOOKUP_TABLE.get(name);
+ return GenericUtils.isEmpty(name) ? null : NAME_LOOKUP_TABLE.get(name);
}
- public int getNumeric() {
- return numeric;
+ /**
+ * Retrieves a signal value given its numeric value
+ *
+ * @param num The signal's numeric value
+ * @return The matching {@link Signal} or {@code null} if no match found
+ * @see #getNumeric()
+ */
+ public static Signal get(int num) {
+ return NUMERIC_LOOKUP_TABLE.get(Integer.valueOf(num));
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/512cbd99/sshd-core/src/main/java/org/apache/sshd/server/StandardEnvironment.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/StandardEnvironment.java b/sshd-core/src/main/java/org/apache/sshd/server/StandardEnvironment.java
new file mode 100644
index 0000000..011b52a
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/StandardEnvironment.java
@@ -0,0 +1,157 @@
+/*
+ * 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.sshd.server;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.apache.sshd.common.channel.PtyMode;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.logging.AbstractLoggingBean;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class StandardEnvironment extends AbstractLoggingBean implements Environment {
+ private final Map<Signal, Set<SignalListener>> listeners;
+ private final Map<String, String> env;
+ private final Map<PtyMode, Integer> ptyModes;
+
+ public StandardEnvironment() {
+ listeners = new ConcurrentHashMap<>(3);
+ env = new ConcurrentHashMap<>();
+ ptyModes = new ConcurrentHashMap<>();
+ }
+
+ @Override
+ public void addSignalListener(SignalListener listener, Signal... signals) {
+ addSignalListener(listener, Arrays.asList(ValidateUtils.checkNotNullAndNotEmpty(signals, "No signals")));
+ }
+
+ @Override
+ public void addSignalListener(SignalListener listener) {
+ addSignalListener(listener, Signal.SIGNALS);
+ }
+
+ /*
+ * NOTE: we don't care if the collection is a Set or not - after all,
+ * we hold the listeners inside a Set, so even if we add several times
+ * the same listener to the same signal set, it is harmless
+ */
+ @Override
+ public void addSignalListener(SignalListener listener, Collection<Signal> signals) {
+ ValidateUtils.checkNotNull(listener, "No listener instance");
+ ValidateUtils.checkNotNullAndNotEmpty(signals, "No signals");
+
+ for (Signal s : signals) {
+ getSignalListeners(s, true).add(listener);
+ }
+ }
+
+ @Override
+ public Map<String, String> getEnv() {
+ return env;
+ }
+
+ @Override
+ public Map<PtyMode, Integer> getPtyModes() {
+ return ptyModes;
+ }
+
+ @Override
+ public void removeSignalListener(SignalListener listener) {
+ ValidateUtils.checkNotNull(listener, "No listener instance");
+ for (Signal s : Signal.SIGNALS) {
+ Set<SignalListener> ls = getSignalListeners(s, false);
+ if (ls != null) {
+ ls.remove(listener);
+ }
+ }
+ }
+
+ public void signal(Signal signal) {
+ Set<SignalListener> ls = getSignalListeners(signal, false);
+ if (log.isDebugEnabled()) {
+ log.debug("signal({}) - listeners={}", signal, ls);
+ }
+
+ if (GenericUtils.isEmpty(ls)) {
+ return;
+ }
+
+ for (SignalListener l : ls) {
+ try {
+ l.signal(signal);
+
+ if (log.isTraceEnabled()) {
+ log.trace("Signal {} to {}", signal, l);
+ }
+ } catch (RuntimeException e) {
+ log.warn("Failed ({}) to signal {} to listener={}: {}",
+ e.getClass().getSimpleName(), signal, l, e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * adds a variable to the environment. This method is called <code>set</code>
+ * according to the name of the appropriate posix command <code>set</code>
+ *
+ * @param key environment variable name
+ * @param value environment variable value
+ */
+ public void set(String key, String value) {
+ // TODO: listening for property changes would be nice too.
+ getEnv().put(key, value);
+ }
+
+ /**
+ * Retrieves the set of listeners registered for a signal
+ *
+ * @param signal The specified {@link Signal}
+ * @param create If {@code true} and no current listeners are mapped then
+ * creates a new {@link Set}
+ * @return The {@link Set} of listeners registered for the signal - may be
+ * {@code null} in case <tt>create</tt> is {@code false}
+ */
+ protected Set<SignalListener> getSignalListeners(Signal signal, boolean create) {
+ Set<SignalListener> ls = listeners.get(signal);
+ if ((ls == null) && create) {
+ synchronized (listeners) {
+ ls = listeners.get(signal);
+ if (ls == null) {
+ ls = new CopyOnWriteArraySet<>();
+ listeners.put(signal, ls);
+ }
+ }
+ }
+
+ return ls;
+ }
+
+ @Override
+ public String toString() {
+ return "env=" + getEnv() + ", modes=" + getPtyModes();
+ }
+}
\ No newline at end of file