<bundle>mvn:org.opendaylight.snmp4sdn/md-model/${project.version}</bundle>
<bundle>mvn:org.opendaylight.snmp4sdn/snmp4sdn/${project.version}</bundle>
<bundle>mvn:org.opendaylight.snmp4sdn/plugin-shell/${project.version}</bundle>
+
+ <bundle>wrap:mvn:com.github.cverges/expect4j/1.9</bundle>
</feature>
</features>
<modules>
<module>third-party/snmpj</module>
- <module>third-party/expect4j</module>
<module>commons/parent</module>
<module>commons/snmp4sdn</module>
<module>mdsal/model</module>
javax.net.ssl,
org.dom4j,<!--xml parser-->
org.dom4j.io,<!--xml parser-->
- <!--org.expect4j //TODO: with this, the following packages are not needed to be listed here?-->
- <!--(a) the following line is needed when expect4j is included in the "Embed-Dependency" section below; otherwise can't build-->
- com.jcraft.jsch, org.apache.commons.net.io, org.apache.commons.net.telnet, org.apache.oro.text, org.apache.oro.text.regex, sunlabs.brazil.util.regexp, tcl.lang.reflect,
-
- org.apache.commons.net.util,<!--this is needed due to those "org.apache.commons.net.*" above in (a)-->
- org.apache.commons.net,<!--this is needed due to the two "org.apache.commons.net.util" above-->
- javax.crypto,javax.crypto.spec,javax.net,<!--this line is needed due to "org.apache.commons.net" above, copy from in it's MANIFEST.MF listed "Import-Package" -->
-
- org.apache.oro.util,<!--this is needed due to those "org.apache.oro.text" above in (a)-->
+ expect4j,
</Import-Package>
<Export-Package>
org.opendaylight.snmp4sdn.internal,<!--should not export-->
org.opendaylight.snmp4sdn,<!--TODO:vlan manager needs to import IVLANService when building, given that vlan manager call snmp4sdn directly-->
org.opendaylight.snmp4sdn.protocol.util,<!--TODO:vlan manager needs to import this in OSGi loading. A more proper place to use this util?-->
- com.jcraft.jsch, org.apache.commons.net, org.apache.commons.net.util, org.apache.commons.net.io, org.apache.commons.net.telnet, org.apache.oro.text, org.apache.oro.text.regex, sunlabs.brazil.util.regexp, tcl.lang.reflect,
- ;-split-package:=merge-first<!--add this line due to when building, "org.apache.oro.text, org.apache.oro.text.regex" above requires to add this parameter-->
+ <!--com.jcraft.jsch, org.apache.commons.net, org.apache.commons.net.util, org.apache.commons.net.io, org.apache.commons.net.telnet, org.apache.oro.text, org.apache.oro.text.regex, sunlabs.brazil.util.regexp, tcl.lang.reflect,--><!--if embed expect4j in snmp4sdn's jar, then need this line-->
+ <!--;-split-package:=merge-first--><!--add this line due to when building, "org.apache.oro.text, org.apache.oro.text.regex" above requires to add this parameter-->
</Export-Package>
<Embed-Dependency>
org.dom4j,
javax.xml,
org.openflow.openflowj,
org.snmpj,
- org.expect4j
- <!--
- ;scope=compile|runtime;inline=true
- --> <!--with this line, the jar needed by expect4j would be included in s4s plugin's jar-->
</Embed-Dependency>
<Embed-Transitive>
false
<version>1.7.0-SNAPSHOT</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.snmp4sdn</groupId>
- <artifactId>org.expect4j</artifactId>
- <version>1.7.0-SNAPSHOT</version>
+ <groupId>com.github.cverges</groupId>
+ <artifactId>expect4j</artifactId>
+ <version>1.9</version>
</dependency>
<dependency><!--need this dependency because "Import-Package" above listed "org.apache.oro.util"-->
<groupId>org.apache.servicemix.bundles</groupId>
* 1. The whole program speed: connection by ExpectUtils.telnet() is faster than Expect4j(socket)
*/
-import org.expect4j.*;//e4j
-import org.expect4j.matches.*;
+import expect4j.Expect4j;
+import expect4j.ExpectState;
+import java.net.Socket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.*;
-import java.net.Socket;
-import java.net.InetAddress;
public class ExpectHandler{
private static Logger logger = LoggerFactory.getLogger(ExpectHandler.class);
+++ /dev/null
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and
-distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright
-owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities
-that control, are controlled by, or are under common control with that entity.
-For the purposes of this definition, "control" means (i) the power, direct or
-indirect, to cause the direction or management of such entity, whether by
-contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
-outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising
-permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including
-but not limited to software source code, documentation source, and configuration
-files.
-
-"Object" form shall mean any form resulting from mechanical transformation or
-translation of a Source form, including but not limited to compiled object code,
-generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made
-available under the License, as indicated by a copyright notice that is included
-in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that
-is based on (or derived from) the Work and for which the editorial revisions,
-annotations, elaborations, or other modifications represent, as a whole, an
-original work of authorship. For the purposes of this License, Derivative Works
-shall not include works that remain separable from, or merely link (or bind by
-name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version
-of the Work and any modifications or additions to that Work or Derivative Works
-thereof, that is intentionally submitted to Licensor for inclusion in the Work
-by the copyright owner or by an individual or Legal Entity authorized to submit
-on behalf of the copyright owner. For the purposes of this definition,
-"submitted" means any form of electronic, verbal, or written communication sent
-to the Licensor or its representatives, including but not limited to
-communication on electronic mailing lists, source code control systems, and
-issue tracking systems that are managed by, or on behalf of, the Licensor for
-the purpose of discussing and improving the Work, but excluding communication
-that is conspicuously marked or otherwise designated in writing by the copyright
-owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
-of whom a Contribution has been received by Licensor and subsequently
-incorporated within the Work.
-
-2. Grant of Copyright License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable copyright license to reproduce, prepare Derivative Works of,
-publicly display, publicly perform, sublicense, and distribute the Work and such
-Derivative Works in Source or Object form.
-
-3. Grant of Patent License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable (except as stated in this section) patent license to make, have
-made, use, offer to sell, sell, import, and otherwise transfer the Work, where
-such license applies only to those patent claims licensable by such Contributor
-that are necessarily infringed by their Contribution(s) alone or by combination
-of their Contribution(s) with the Work to which such Contribution(s) was
-submitted. If You institute patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Work or a
-Contribution incorporated within the Work constitutes direct or contributory
-patent infringement, then any patent licenses granted to You under this License
-for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution.
-
-You may reproduce and distribute copies of the Work or Derivative Works thereof
-in any medium, with or without modifications, and in Source or Object form,
-provided that You meet the following conditions:
-
-You must give any other recipients of the Work or Derivative Works a copy of
-this License; and
-You must cause any modified files to carry prominent notices stating that You
-changed the files; and
-You must retain, in the Source form of any Derivative Works that You distribute,
-all copyright, patent, trademark, and attribution notices from the Source form
-of the Work, excluding those notices that do not pertain to any part of the
-Derivative Works; and
-If the Work includes a "NOTICE" text file as part of its distribution, then any
-Derivative Works that You distribute must include a readable copy of the
-attribution notices contained within such NOTICE file, excluding those notices
-that do not pertain to any part of the Derivative Works, in at least one of the
-following places: within a NOTICE text file distributed as part of the
-Derivative Works; within the Source form or documentation, if provided along
-with the Derivative Works; or, within a display generated by the Derivative
-Works, if and wherever such third-party notices normally appear. The contents of
-the NOTICE file are for informational purposes only and do not modify the
-License. You may add Your own attribution notices within Derivative Works that
-You distribute, alongside or as an addendum to the NOTICE text from the Work,
-provided that such additional attribution notices cannot be construed as
-modifying the License.
-You may add Your own copyright statement to Your modifications and may provide
-additional or different license terms and conditions for use, reproduction, or
-distribution of Your modifications, or for any such Derivative Works as a whole,
-provided Your use, reproduction, and distribution of the Work otherwise complies
-with the conditions stated in this License.
-
-5. Submission of Contributions.
-
-Unless You explicitly state otherwise, any Contribution intentionally submitted
-for inclusion in the Work by You to the Licensor shall be under the terms and
-conditions of this License, without any additional terms or conditions.
-Notwithstanding the above, nothing herein shall supersede or modify the terms of
-any separate license agreement you may have executed with Licensor regarding
-such Contributions.
-
-6. Trademarks.
-
-This License does not grant permission to use the trade names, trademarks,
-service marks, or product names of the Licensor, except as required for
-reasonable and customary use in describing the origin of the Work and
-reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty.
-
-Unless required by applicable law or agreed to in writing, Licensor provides the
-Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
-including, without limitation, any warranties or conditions of TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
-solely responsible for determining the appropriateness of using or
-redistributing the Work and assume any risks associated with Your exercise of
-permissions under this License.
-
-8. Limitation of Liability.
-
-In no event and under no legal theory, whether in tort (including negligence),
-contract, or otherwise, unless required by applicable law (such as deliberate
-and grossly negligent acts) or agreed to in writing, shall any Contributor be
-liable to You for damages, including any direct, indirect, special, incidental,
-or consequential damages of any character arising as a result of this License or
-out of the use or inability to use the Work (including but not limited to
-damages for loss of goodwill, work stoppage, computer failure or malfunction, or
-any and all other commercial damages or losses), even if such Contributor has
-been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability.
-
-While redistributing the Work or Derivative Works thereof, You may choose to
-offer, and charge a fee for, acceptance of support, warranty, indemnity, or
-other liability obligations and/or rights consistent with this License. However,
-in accepting such obligations, You may act only on Your own behalf and on Your
-sole responsibility, not on behalf of any other Contributor, and only if You
-agree to indemnify, defend, and hold each Contributor harmless for any liability
-incurred by, or claims asserted against, such Contributor by reason of your
-accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work
-
-To apply the Apache License to your work, attach the following boilerplate
-notice, with the fields enclosed by brackets "[]" replaced with your own
-identifying information. (Don't include the brackets!) The text should be
-enclosed in the appropriate comment syntax for the file format. We also
-recommend that a file or class name and description of purpose be included on
-the same "printed page" as the copyright notice for easier identification within
-third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<actions>
- <action>
- <actionName>run</actionName>
- <packagings>
- <packaging>jar</packaging>
- </packagings>
- <goals>
- <goal>package</goal>
- <goal>org.codehaus.mevenide:netbeans-run-plugin:RELEASE:run-jar</goal>
- </goals>
- <properties>
- <netbeans.jar.run.jvmparams>-Djava.util.logging.config.file=logging.properties</netbeans.jar.run.jvmparams>
- </properties>
- </action>
- <action>
- <actionName>debug</actionName>
- <packagings>
- <packaging>jar</packaging>
- </packagings>
- <goals>
- <goal>package</goal>
- <goal>org.codehaus.mevenide:netbeans-run-plugin:RELEASE:run-jar</goal>
- </goals>
- <properties>
- <jpda.listen>true</jpda.listen>
- <netbeans.jar.run.jvmparams>-Djava.util.logging.config.file=logging.properties</netbeans.jar.run.jvmparams>
- <netbeans.jar.run.debugparams>-Xdebug -Djava.compiler=none -Xnoagent -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address}</netbeans.jar.run.debugparams>
- </properties>
- </action>
-</actions>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>org.opendaylight.snmp4sdn</groupId>
- <artifactId>org.expect4j</artifactId>
- <version>1.7.0-SNAPSHOT</version>
- <packaging>bundle</packaging>
-
- <name>expect4j</name>
- <url>http://github.com/cverges/expect4j</url>
- <description>A Java implementation of the standard Expect library</description>
-
- <scm>
- <connection>scm:git:https://git.opendaylight.org/snmp4sdn.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/snmp4sdn.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://git.opendaylight.org/gerrit/gitweb?p=snmp4sdn.git;a=summary</url>
- </scm>
-
- <licenses>
- <license>
- <name>The Apache Software License, Version 2.0</name>
- <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
- </license>
- </licenses>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <nexusproxy>https://nexus.opendaylight.org/content</nexusproxy>
- <sitedeploy>dav:https://nexus.opendaylight.org/content/sites/site</sitedeploy>
- <releaseplugin.version>2.3.2</releaseplugin.version>
- </properties>
-
- <!-- The following could be removed, achieved by ~/.m2/settings.xml, as ODL required-->
- <repositories>
- <!--<repository>
- <id>ebr-bundles-external</id>
- <name>ebr-bundles-external</name>
- <url>${nexusproxy}/repositories/ebr-bundles-external/</url>
- </repository>-->
-
- <!--for library not in ODL's nexus-->
- <repository>
- <id>com.springsource.repository.bundles.release</id>
- <name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name>
- <url>http://repository.springsource.com/maven/bundles/release</url>
- </repository>
- <repository>
- <id>com.springsource.repository.bundles.external</id>
- <name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
- <url>http://repository.springsource.com/maven/bundles/external</url>
- </repository>
-
- </repositories>
- <!-- End of...coudl be removed, achieved by ~/.m2/settings.xml, as ODL required-->
-
- <build>
- <plugins>
- <!--<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.9.1</version>
- <configuration>
- <show>private</show>
- <nohelp>true</nohelp>
- <detectLinks>true</detectLinks>
- <links>
- <link>http://docs.oracle.com/javase/7/docs/api</link>
- </links>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-sources</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-javadocs</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>-->
-
- <!--snmpj-->
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>2.3.6</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.servicemix.bundles.oro,<!--new add (reference to the answer in http://stackoverflow.com/questions/18415375/unable-to-resolve-1-0-missing-requirement-1-0-osgi-wiring-package-osgi-wi)-->
- jsch,
- commons-net,
- com.springsource.tcl.lang.jacl,
- tcl.lang.reflect<!--add due to when install and then start expect4j's bundle, appear: "missing tcl.lang.reflect", so I find this in jcraft's pom-->
- </Export-Package>
- <Embed-Dependency><!--new add (imitate snmp4sdn plugin)-->
- org.apache.servicemix.bundles.oro,
- jsch,
- commons-net,
- com.springsource.tcl.lang.jacl
- </Embed-Dependency><!--end of new add-->
- </instructions>
- <manifestLocation>${project.basedir}/META-INF</manifestLocation>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <source>1.6</source>
- <target>1.6</target>
- </configuration>
- </plugin>
-
-
- </plugins>
- <pluginManagement>
- <plugins>
- <plugin>
- <artifactId>maven-enforcer-plugin</artifactId>
- <version>1.1.1</version>
- <executions>
- <execution>
- <id>enforce-banned-dependencies</id>
- <goals>
- <goal>enforce</goal>
- </goals>
- <configuration>
- <rules>
- <bannedDependencies>
- <searchTransitive>true</searchTransitive>
- <excludes>
- <exclude>commons-logging</exclude>
- <exclude>org.slf4j:1.5*</exclude>
- <exclude>org.slf4j:1.6*</exclude>
- </excludes>
- </bannedDependencies>
- </rules>
- <fail>true</fail>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-
- <distributionManagement>
- <!--snmpj-->
- <!-- OpenDayLight Released artifact -->
- <repository>
- <id>opendaylight-release</id>
- <url>${nexusproxy}/repositories/opendaylight.release/</url>
- </repository>
- <!-- OpenDayLight Snapshot artifact -->
- <snapshotRepository>
- <id>opendaylight-snapshot</id>
- <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
- </snapshotRepository>
- <!-- Site deployment -->
- <site>
- <id>website</id>
- <url>${sitedeploy}</url>
- </site>
- </distributionManagement>
-
- <dependencies>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.2</version><!--1.7.5 was used and thus cause dependency skew from the rest of snmp4sdn and the controller which used 1.7.2 then-->
- </dependency>
- <dependency>
- <groupId>org.apache.servicemix.bundles</groupId>
- <artifactId>org.apache.servicemix.bundles.oro</artifactId>
- <version>2.0.8_6</version>
- </dependency>
- <dependency>
- <groupId>com.jcraft</groupId>
- <artifactId>jsch</artifactId>
- <version>0.1.50</version>
- </dependency>
- <dependency>
- <groupId>commons-net</groupId>
- <artifactId>commons-net</artifactId>
- <version>3.3</version>
- </dependency>
- <dependency>
- <groupId>net.sourceforge.tcljava</groupId>
- <artifactId>com.springsource.tcl.lang</artifactId>
- <version>1.4.1</version>
- </dependency>
- <dependency>
- <groupId>net.sourceforge.tcljava</groupId>
- <artifactId>com.springsource.tcl.lang.jacl</artifactId>
- <version>1.4.1</version>
- </dependency>
- </dependencies>
-</project>
-<!-- vim: set ts=4 expandtab: -->
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.logging.Level;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Responsible for absorbing everything from stream and to maintain a
- * buffer. This subclass of {@link Consumer} blocks while performing
- * these operations and needs to be asynchronously managed.
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class BlockingConsumer extends ConsumerImpl {
- /**
- * Interface to the Java 2 platform's core logging facilities.
- */
- private static final Logger logger = LoggerFactory.getLogger(BlockingConsumer.class);
-
- /**
- * TODO
- */
- Boolean callerProcessing = Boolean.FALSE;
-
- /**
- * TODO
- */
- boolean foundMore = false;
-
- /**
- * Creates a <code>BlockingConsumer</code> instance based on an
- * {@link IOPair} concrete instance.
- *
- * @param pair the <code>IOPair</code> concrete instance that
- * provides access to the reader/writer streams
- */
- public BlockingConsumer(IOPair pair) {
- super(pair);
- logger.trace("Created new BlockingConsumer instance " + this + "using IOPair " + pair);
- }
-
- /**
- * Starts the <code>BlockingConsumer</code> in processing the reader
- * stream.
- *
- * @TODO Handle timeout of zero to expect, that shouldn't wait
- */
- public void run() {
- logger.trace("BlockingConsumer " + this + " starting data processing");
-
- int length;
- char cs[] = new char[256];
- Reader reader = pair.getReader();
-
- while (!stopRequested && !foundEOF) {
- try {
- logger.trace("BlockingConsumer " + this + " reading from reader");
- length = reader.read(cs); // blocking
- } catch (IOException ioe) {
- // The reader most likely closed on us.
- logger.warn("Caught an exception while reading: " + ioe);
- logger.debug("Assuming EOF");
- foundEOF = true;
- break;
- }
-
- if (length == -1) { //EOF
- logger.debug("BlockingConsumer " + this + " detected EOF");
- logger.trace("Remaining buffer: " + buffer.toString());
- foundEOF = true;
- break;
- }
-
- // don't modify the buffer while processing is happening
- // written as while loop to prevent spurious interrupts
- logger.trace("BlockingConsumer " + this + " waiting for synchronized access before appending");
- synchronized(this) { // this could be just before notify, I think
- if (logger.isDebugEnabled()) {
- logger.debug("BlockingConsumer " + this + " appending " + length + " characters to the buffer");
-
- // TODO: this replace operation is done a few places, perhaps utility class?
- String print = new String(cs, 0, length);
- print = print.replaceAll("\n", "\\\\n");
- print = print.replaceAll("\r", "\\\\r");
- logger.debug("Adding to buffer: " + print);
-
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < length; i++)
- sb.append("," + ((int) cs[i]) );
- logger.trace("Codes: " + sb.toString());
- }
- buffer.append(cs, 0, length); // thread safe
-
- /**
- * TODO Trim down buffer. This current method won't work if a resume comes in, since it's offset
- * will be invalid once this delete method runs
- *
- * // since we only added one char, we should only have to remove one
- * if (buffer.length() > BUFFERMAX)
- * buffer.delete(0, BUFFERMAX - buffer.length());
- */
-
- logger.trace("BlockingConsumer " + this + " notifying listeners of buffer change");
- notify(); // seeing that we read something, wake people up
- } // end synchronized(this)
- } // end while loop
-
- logger.trace("BlockingConsumer " + this + " notifying listeners upon ceasing");
- synchronized(this) {
- notify();
- }
-
- if (stopRequested) {
- logger.debug("BlockingConsumer " + this + " stop requested");
- pair.close();
- }
-
- if (foundEOF)
- logger.debug("BlockingConsumer " + this + " found EOF to stop while loop");
- }
-
- /**
- * TODO
- *
- * @param timeout timeout in milliseconds
- * @TODO what is something came in between when we last checked and
- * when this method is called
- */
- public void waitForBuffer(long timeout) {
- if (foundEOF) {
- logger.trace("BlockingConsumer " + this + " wanted to wait for buffer but found EOF");
- return;
- }
-
- logger.trace("BlockingConsumer " + this + " ynching on this to wait");
- logger.trace("BlockingConsumer " + this + " waiting for synchronized access before waiting");
- synchronized(this) {
- try {
- if (timeout > 0) {
- logger.trace("BlockingConsumer " + this + " waiting for " + timeout + " msec for some additional event");
- wait(timeout);
- } else {
- logger.trace("BlockingConsumer " + this + " waiting forever for some additional event");
- wait();
- }
- } catch (InterruptedException ie) {
- logger.trace("BlockingConsumer " + this + " woken up while waiting for buffer");
- }
- }
- }
-
- /**
- * TODO
- *
- * @return TODO
- */
- public String pause() {
- // TODO mark offset, so that it can be trimmed by resume coming in later
- String currentBuffer;
- currentBuffer = buffer.toString();
- return currentBuffer;
- }
-
- /**
- * Resume processing from the specified offset.
- *
- * @param offset the offset into the buffer (1-indexed) from which
- * to start
- */
- public void resume(int offset) {
- if (offset < 0)
- return;
-
- synchronized(this) {
- logger.trace("BlockingConsumer " + this + " moving buffer up by " + offset);
- StringBuffer smaller = buffer.delete(0, offset); // + 1
- }
- }
-
- /**
- * A method to test the <code>BlockingConsumer</code> class independently.
- *
- * @param args command line arguments (none used)
- */
- public static void main(String args[]) throws Exception {
- final StringBuffer buffer = new StringBuffer("The lazy fox");
-
- Thread t1 = new Thread() {
- public void run() {
- synchronized(buffer) {
- buffer.delete(0,4);
- buffer.append(" in the middle");
- System.err.println("Middle");
- try {
- Thread.sleep(4000);
- } catch (Exception e) {}
- buffer.append(" of fall");
- System.err.println("Fall");
- }
- }
- };
-
- Thread t2 = new Thread() {
- public void run() {
- try {
- Thread.sleep(1000);
- } catch (Exception e) {}
- buffer.append(" jump over the fence");
- System.err.println("Fence");
- }
- };
-
- t1.start();
- t2.start();
-
- t1.join();
- t2.join();
-
- System.err.println(buffer);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-/**
- * A <code>Closure</code> is a snippet of code that can access variables
- * from one context while running in another. <code>Closure</code>s are
- * used with Expect4J to define handlers that are executed whenever a
- * corresponding {@link expect4j.matches.Match} is found.
- * <p>
- * Currently in Java, all variables accessed by the <code>Closure</code>
- * need to be marked as <code>final</code>. To export information from
- * the <code>Closure</code> context to the context in which the
- * <code>Closure</code> is defined, consider using buffers such as
- * <code>final {@link java.lang.StringBuffer}</code>.
- * <pre>
- * TODO: examples
- * </pre>
- *
- * @author Chris Verges
- * @author Justin Ryan
- * @see <a href="http://en.wikipedia.org/wiki/Closure_(computer_science)">Wikipedia</a>
- */
-public interface Closure {
- /**
- * The main execution of the <code>Closure</code>. All care should
- * be taken to avoid throwing <code>Exception</code>s, though the
- * calling context is responsible for catching any thrown.
- * Information about the triggering condition, such as the match or
- * submatch strings, can be obtained through the {@link ExpectState}
- * instance provided.
- *
- * @param state the contextual information on why this
- * <code>Closure</code> was executed
- * @throws Exception in an extreme case
- */
- public void run(ExpectState state) throws Exception;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.io.IOException;
-
-/**
- * Responsible for absorbing everything from stream and to maintain a
- * buffer.
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public interface Consumer extends Runnable {
- /**
- * Starts the <code>Consumer</code> in processing the reader
- * stream.
- */
- public void run();
-
- /**
- * TODO
- *
- * @param timeout timeout in milliseconds
- * @TODO what is something came in between when we last checked and
- * when this method is called
- */
- public void waitForBuffer(long timeout);
-
- /**
- * Passes data to the writer stream for remote execution from the
- * <code>Consumer</code>. I'm not really sure why this is useful or
- * desired, but the ability exists. Use with caution.
- *
- * @param data the data to pass to the writer
- * @throws IOException if an error occurs with the writer stream
- * @see Expect4j#send(String)
- */
- public void send(String data) throws IOException;
-
- /**
- * TODO
- *
- * @return TODO
- */
- public String pause();
-
- /**
- * Resume processing from the beginning of the buffer.
- */
- public void resume();
-
- /**
- * Resume processing from the specified offset.
- *
- * @param offset the offset into the buffer (1-indexed) from which
- * to start
- */
- public void resume(int offset);
-
- /**
- * Requests the <code>Consumer</code> to stop processing data at its
- * next convenient time.
- */
- public void stop();
-
- /**
- * Returns a boolean flag on whether the EOF marker has been detected.
- *
- * @return <code>true</code> if EOF has been detected,
- * <code>false</code> otherwise
- */
- public boolean foundEOF();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.io.Writer;
-import java.io.IOException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author justin
- */
-public abstract class ConsumerImpl implements Consumer {
- /**
- * Interface to the Java 2 platform's core logging facilities.
- */
- private static final Logger logger = LoggerFactory.getLogger(ConsumerImpl.class);
-
- /**
- * The maximum size of the buffer, currently set to 16 KB.
- */
- public static final int BUFFERMAX = 16 * 1024;
-
- /**
- * A buffer containing the unprocessed data received over the reader
- * stream.
- */
- StringBuffer buffer;
-
- /**
- * The reader and writer streams being managed by this
- * <code>Consumer</code>.
- */
- IOPair pair;
-
- /**
- * A flag to indicate whether processing should continue.
- */
- boolean stopRequested = false;
-
- /**
- * A flag to indicate whether the EOF marker was detected on the
- * reader stream.
- */
- boolean foundEOF = false;
-
- /**
- * Creates a <code>ConsumerImpl</code> instance based on an
- * {@link IOPair} concrete instance.
- *
- * @param pair the <code>IOPair</code> concrete instance that
- * provides access to the reader/writer streams
- */
- public ConsumerImpl(IOPair pair) {
- this.pair = pair;
- buffer = new StringBuffer();
- }
-
- /**
- * Passes data to the writer stream for remote execution from the
- * <code>Consumer</code>. I'm not really sure why this is useful or
- * desired, but the ability exists. Use with caution.
- *
- * @param data the data to pass to the writer
- * @throws IOException if an error occurs with the writer stream
- * @see Expect4j#send(String)
- */
- public void send(String data) throws IOException {
- String printStr = null;
- if (logger.isDebugEnabled()) {
- printStr = data;
- printStr = printStr.replaceAll("\\r", "\\\\r");
- printStr = printStr.replaceAll("\\n", "\\\\n");
- }
-
- synchronized(this) {
- logger.debug("Sending to writer: " + printStr);
- Writer writer = pair.getWriter();
- writer.write(data);
- writer.flush();
- }
- }
-
- /**
- * Resume processing from the beginning of the buffer.
- */
- public void resume() {
- resume(-1);
- }
-
- /**
- * Requests the <code>Consumer</code> to stop processing data at its
- * next convenient time.
- */
- public void stop() {
- logger.trace("Requesting the Consumer to stop processing data");
- stopRequested = true;
- }
-
- /**
- * Returns a boolean flag on whether the EOF marker has been detected.
- *
- * @return <code>true</code> if EOF has been detected,
- * <code>false</code> otherwise
- */
- public boolean foundEOF() {
- return foundEOF;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import org.expect4j.matches.*;
-
-// TODO: replace these with specific class imports
-import java.io.*;
-import java.util.*;
-import org.apache.oro.text.regex.*;
-
-import java.net.Socket;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Provides an API for interacting with the reader/writer streams to be
- * managed. <code>Expect4j</code> provides both <code>send</code> and
- * <code>expect</code> functionality, like is found with the canonical
- * Expect implementation. A variety of {@link Match}ers with associated
- * {@link Closure}s may be used to implement complex Expect parsers.
- * <p>
- * <pre>
- * import org.expect4j.Expect4j;
- * import java.io.InputStream;
- * import java.io.OutputStream;
- *
- * InputStream is = ...;
- * OutputStream os = ...;
- *
- * Expect4j expect = new Expect4j(is, os);
- * expect.setDefaultTimeout(10 * 1000);
- *
- * final StringBuffer someTextBuffer = new StringBuffer();
- *
- * expect.expect(new Match[] {
- * new GlobMatch("text defined as a glob pattern", new Closure() {
- * public void run(ExpectState state) {
- * state.addVar("found-glob", "true");
- * state.exp_continue();
- * }
- * }),
- * new RegExpMatch("(uses)? PERL(\\d+) regular expressions", new Closure() {
- * public void run(ExpectState state) {
- * someTextBuffer.append(state.getMatch(2));
- * state.exp_continue_reset_timer();
- * }
- * }),
- * new EofMatch(new Closure() {
- * public void run(ExpectState state) {
- * state.addVar("eof-found", "true");
- * }
- * }),
- * new TimeoutMatch(new Closure() {
- * public void run(ExpectState state) {
- * state.addVar("timed-out", "true");
- * }
- * })
- * });
- *
- * Boolean eofFound = new Boolean( (String)expect.getLastState().getVar("eof-found") );
- * String someText = someTextBuffer.toString();</pre>
- * This implementation currently does not provide matching
- * <code>interact</code> functionality.
- *
- * @author Chris Verges
- * @author Justin Ryan
- * @TODO "expect eof"
- */
-public class Expect4j {
- /**
- * Interface to the Java 2 platform's core logging facilities.
- */
- private static final Logger logger = LoggerFactory.getLogger(Expect4j.class);
-
- /**
- * TODO
- */
- IOPair pair;
-
- /**
- * TODO
- */
- Consumer consumer;
-
- /**
- * TODO
- */
- Thread consumerThread;
-
- /**
- * TODO
- */
- Perl5Matcher matcher;
-
- /**
- * TODO
- */
- PatternMatcherInput input;
-
- /**
- * Create an <code>Expect4j</code> instance based on an {@link
- * IOPair} concrete instance.
- *
- * @param pair the <code>IOPair</code> concrete instance that
- * provides access to the reader/writer streams
- */
- public Expect4j(IOPair pair) {
- logger.trace("Creating new Expect4J instance " + this + " using IOPair " + pair);
-
- // Matching
- matcher = new Perl5Matcher();
- matcher.setMultiline(true);
- input = new PatternMatcherInput("");
-
- // IO
- this.pair = pair;
- if (true) {
- consumer = new BlockingConsumer(pair);
- } else {
- // TODO: this section is never hit due to the "if (true)" above
- consumer = new PollingConsumer(pair);
- }
-
- consumerThread = new Thread(consumer);
- consumerThread.setDaemon(true);
- logger.trace("Starting consumer thread " + consumerThread + " for Expect4J instance " + this);
- consumerThread.start();
-
- mode = STATE_INITIALIZED;
- }
-
- /**
- * Creates an <code>Expect4j</code> instance based on a {@link
- * java.net.Socket}.
- *
- * @param socket the <code>Socket</code> to manage
- */
- public Expect4j(Socket socket) throws IOException {
- this(socket.getInputStream(), socket.getOutputStream());
- logger.trace("Created Expect4J instance " + this + " based on Socket " + socket);
- }
-
- /**
- * Creates an <code>Expect4j</code> instance based on an {@link
- * java.io.InputStream} and {@link java.io.OutputStream}.
- *
- * @param is the <code>InputStream</code> to use for reading data
- * @param os the <code>OutputStream</code> to use for writing data
- */
- public Expect4j(InputStream is, OutputStream os) {
- this( new StreamPair(is, os) );
- logger.trace("Created Expect4J instance " + this + " based on InputStream " + is + " and OutputStream " + os);
- }
-
- /**
- * Creates an <code>Expect4j</code> instance based on a spawned
- * {@link java.lang.Process}.
- *
- * @param process the spawned <code>Process</code> that will be managed
- */
- public Expect4j(Process process) {
- this( process.getInputStream(), process.getOutputStream() );
- logger.trace("Created Expect4J instance " + this + " based on Process " + process);
- }
-
- /**
- * Class has not had its core variables set yet.
- */
- static final int STATE_UNINIT = 1;
-
- /**
- * Class has been given the appropriate arguments.
- */
- static final int STATE_INITIALIZED = 2;
-
- /**
- * Class has been given patterns, and it is currently parsing the streams.
- */
- static final int STATE_EXPECTING = 3;
-
- /**
- * Class found a match to a pattern, and it can receive new patterns.
- */
- static final int STATE_EXPECTED = 4;
-
- /**
- * State of processing.
- */
- int mode = STATE_UNINIT;
-
- /**
- * Passes data to the writer stream for remote execution. This
- * function simulates the Expect <code>exp_send</code> function.
- *
- * @param data the data to pass to the writer
- * @throws IOException if an error occurs with the writer stream
- * @see <a href="http://wiki.tcl.tk/14317">http://wiki.tcl.tk/14317</a>
- * @TODO might have to strip <code>\n</code> and replace with
- * <code>\r</code>
- */
- public void send(String data) throws IOException {
- consumer.send(data);
- }
-
- /**
- * An error code returned by <code>Expect4j.expect</code> to
- * indicate that no match was found and no re-attempt was made.
- */
- public static final int RET_TRIED_ONCE = -4;
-
- /**
- * An error code returned by <code>Expect4j.expect</code> to
- * indicate that the end of file marker was encountered when
- * accessing the reader stream.
- */
- public static final int RET_EOF = -3;
-
- /**
- * An error code returned by <code>Expect4j.expect</code> to
- * indicate that the timeout value expired prior to finding a
- * concluding match. It should be noted that matches may have been
- * found prior to this being returned, but their associated {@link
- * Closure}s may have continued processing via {@link
- * ExpectState#exp_continue}.
- */
- public static final int RET_TIMEOUT = -2;
-
- /**
- * An error code returned by <code>Expect4j.expect</code> to
- * indicate that some unforeseen condition occurred.
- */
- public static final int RET_UNKNOWN = -1;
-
- /**
- * Attempts to detect the provided pattern as an exact match.
- * @param pattern the pattern to find in the reader stream
- * @return the number of times the pattern is found,
- * or an error code
- * @throws MalformedPatternException if the pattern is invalid
- * @throws Exception if a generic error is encountered
- */
- public int expect(String pattern) throws MalformedPatternException, Exception {
- logger.trace("Searching for '" + pattern + "' in the reader stream");
- return expect(pattern, null);
- }
-
- /**
- * Attempts to detect the provided pattern and executes the provided
- * {@link Closure} if it is detected.
- * @param pattern the pattern to find in the reader stream
- * @param handler the handler to execute if the pattern is found
- * @return the number of times the pattern is found,
- * or an error code
- * @throws MalformedPatternException if the pattern is invalid
- * @throws Exception if a generic error is encountered while
- * processing the {@link Closure}
- */
- public int expect(String pattern, Closure handler) throws MalformedPatternException, Exception {
- logger.trace("Searching for '" + pattern + "' in the reader stream and executing Closure " + handler + " if found");
- PatternPair match = new GlobMatch(pattern, handler);
- List /* <PatternMatch> */ list = new ArrayList();
- list.add(match);
- return expect(list);
- }
-
- /**
- * Attempts to detect the patterns contained in the {@link Match}
- * list and executes their associated {@link Closure}s if any are
- * detected.
- * @param args the list of patterns and associated {@link Closure}s
- * to execute
- * @return the number of times the pattern is found,
- * or an error code
- * @throws MalformedPatternException if the pattern(s) is/are invalid
- * @throws Exception if a generic error is encountered while
- * processing the {@link Closure}
- */
- public int expect(Match args[]) throws MalformedPatternException, Exception {
- logger.trace("Searching for " + args.length + " patterns in the reader stream");
- List pairs = new ArrayList();
- for (int i = 0; i < args.length; i++) {
- Match match = args[i];
- pairs.add(match);
- }
- return expect(pairs);
- }
-
- /**
- * Attempts to detect the patterns contained in the {@link
- * java.util.List} list and executes their associated {@link
- * Closure}s if any are detected.
- * @param pairs the list of patterns and associated {@link Closure}s
- * to execute
- * @return the number of times the pattern is found,
- * or an error code
- * @throws Exception if a generic error is encountered while
- * processing the {@link Closure}
- */
- public int expect(final List /* <Match> */ pairs) throws Exception {
- logger.trace("Searching for " + pairs.size() + " patterns in the reader stream");
-
- // Buckets
- EofMatch eofMatch = null;
- TimeoutMatch timeoutMatch = null;
- List /* <PatternPair> */ patternMatches = new ArrayList();
-
- // Fill buckets in one swoop
- Iterator iter = pairs.iterator();
- while (iter.hasNext()) {
- Object match = iter.next();
- if (!(match instanceof Match)) {
- logger.debug("Object " + match + " is not of type expect4j.matches.Match, cannot use as a pattern");
- continue;
- } else if (match instanceof PatternPair) {
- logger.trace("Searching for PatternPair " + match + " in the reader stream");
- patternMatches.add( match );
- } else if (match instanceof TimeoutMatch) {
- logger.trace("Registering custom TimeoutMatch handler " + match);
- timeoutMatch = (TimeoutMatch) match;
- } else if (match instanceof EofMatch) {
- logger.trace("Registering custom EofMatch handler " + match);
- eofMatch = (EofMatch) match;
- } else {
- logger.debug("Unexpected match object " + match + " found in the pattern list, ignoring");
- }
- }
-
- // if( eofMatch == null ) eofMatch = new EofMatch();
- // if( timeoutMatch == null ) // that's ok
- long timeout;
- if (timeoutMatch != null && timeoutMatch.getTimeout() != TIMEOUT_NOTSET)
- timeout = timeoutMatch.getTimeout();
- else
- timeout = defaultTimeout;
- long startTime = System.currentTimeMillis();
- long endTime = startTime + timeout;
- logger.debug("Timeout set to " + timeout + " milliseconds, expires at " + endTime);
-
- boolean foundTimeout = false;
- boolean foundEof = false;
- int index = RET_UNKNOWN;
-
- // New states are based on g_state and they need to see a null
- // g_state on the first match
- g_state = null;
-
- // Primary loop, which only really continues if
- // State.exp_continue() is called or no match was found
- String toMatch = null; // from last pause call
- while (true) {
- if (timeout != TIMEOUT_FOREVER && System.currentTimeMillis() >= endTime) {
- logger.debug("Detection timeout expired");
- foundTimeout = true;
- break;
- }
-
- synchronized(consumer) { // while matching
- toMatch = consumer.pause();
- logger.trace("Size of toMatch is " + toMatch.length());
- // make sure to resume before any break/continue
- foundEof = consumer.foundEOF(); // has to be called before resume
-
- input.setInput(toMatch);
-
- logger.debug("Finding first match using >>>" + printBuffer() + "<<< as the haystack");
-
- boolean foundMatch = false;
- try {
- foundMatch = runFirstMatch(patternMatches);
- } catch (Exception e) {
- logger.warn("Forwarding an exception that occurred in a Closure: " + e);
- consumer.resume();
- throw e;
- }
-
- // Both paths call resume.
- if (foundMatch) {
- int matchedWhere = g_state.getMatchedWhere();
- int matchedLength = g_state.getMatch().length();
- logger.debug("Matched @ " + matchedWhere + " with a length of " + matchedLength);
-
- // resume consumer, at a later offset
- consumer.resume(matchedWhere + matchedLength);
-
- // find index to return
- PatternPair singlepair = (PatternPair) patternMatches.get( g_state.getPairIndex() );
- logger.trace("Pair found " + singlepair.getPattern().getPattern() );
- index = pairs.indexOf( singlepair );
- logger.trace("Index found " + index);
-
- if (!g_state.shouldContinue()) {
- logger.trace("NOT Continuing");
- break;
- } else {
- logger.trace("Continuing");
- }
-
- if (g_state.shouldResetTimer()) {
- // keep start time where it is
- endTime = System.currentTimeMillis() + timeout;
- }
- continue; // skips waitForBuffer since buffer might already have what we're looking for
-
- } else {
- logger.trace("Nothing found, resuming consumer");
- consumer.resume();
- if (timeout == TIMEOUT_NEVER) {
- // The timeout variables tells us that we shouldn't try again
- // TODO Find out if this triggers the Timeout match
- index = RET_TRIED_ONCE;
- break;
- }
- }
- if (foundEof) {
- logger.debug("Found EOF");
- break;
- }
-
- if (timeout == TIMEOUT_FOREVER) {
- consumer.waitForBuffer(TIMEOUT_FOREVER);
- } else {
- long singleTimeout = endTime - System.currentTimeMillis();
- logger.trace("singleTimeout: " + singleTimeout);
- if (timeout != TIMEOUT_FOREVER && singleTimeout <= 0) {
- // we might have gone over the timeout already
- // restart while loop, that the typical logic takes hold
- continue;
- }
- logger.debug("Waiting for more input");
- consumer.waitForBuffer(singleTimeout);
- }
- }
- } // end while
- logger.trace("Leaving main while loop");
-
- Match lastmile = null;
- String lastmileBuffer = null;
- if (foundTimeout) { //removed index == -1
- logger.trace("Dealing with Timeout");
- if (timeoutMatch == null)
- index = RET_TIMEOUT; // Timeout with a Timeout match
- else
- lastmile = timeoutMatch;
- }
-
- if (foundEof) {
- logger.info("Dealing with EOF " + eofMatch);
- if (eofMatch != null) {
- lastmileBuffer = toMatch;
- lastmile = eofMatch;
- } else if (index == -1) {
- index = RET_EOF;
- }
- }
-
- // We're in the final stretch, but we might have one last closure to run.
- if (lastmile != null) {
- logger.trace("Running last mile");
-
- //TODO provide buffer vars for EOF
- Closure closure = lastmile.getClosure();
- index = pairs.indexOf(lastmile);
-
- ExpectState state = prepareClosure(index, lastmileBuffer);
- try {
- if (closure != null)
- closure.run(state);
- } catch (Exception e) {
- logger.warn("Forwarding an exception that occurred in a Closure: " + e);
- logger.trace("Closure body: " + closure.toString());
- throw e;
- } finally {
- g_state = state;
- }
- }
- return index;
- }
-
- /**
- * An internal helper function that converts the input buffer into a
- * printable <code>String</code>.
- *
- * @return the input buffer as a printable <code>String</code>
- */
- public String printBuffer() {
- String javaStr = new String(input.getBuffer());
- javaStr = javaStr.replaceAll("\\r", "\\\\r");
- javaStr = javaStr.replaceAll("\\n", "\\\\n");
- return javaStr;
- }
-
- /**
- * TODO
- *
- * @param pairIndex TODO
- * @param buffer TODO
- * @return TODO
- */
- protected ExpectState prepareClosure(int pairIndex, String buffer) {
- ExpectState state;
- Map prevMap = null;
- if (g_state != null)
- prevMap = g_state.getVars();
-
- state = new ExpectState(pairIndex, buffer, prevMap);
-
- return state;
- }
-
- /**
- * Don't use input, it's match values might have been reset in the
- * loop that looks for the first possible match.
- *
- * @param pairIndex TODO
- * @param result TODO
- * @return TODO
- */
- protected ExpectState prepareClosure(int pairIndex, MatchResult result) {
- /* TODO: potentially remove this?
- {
- System.out.println( "Begin: " + result.beginOffset(0) );
- System.out.println( "Length: " + result.length() );
- System.out.println( "Current: " + input.getCurrentOffset() );
- System.out.println( "Begin: " + input.getMatchBeginOffset() );
- System.out.println( "End: " + input.getMatchEndOffset() );
- //System.out.println( "Match: " + input.match() );
- //System.out.println( "Pre: >" + input.preMatch() + "<");
- //System.out.println( "Post: " + input.postMatch() );
- }
- */
-
- // Prepare Closure environment
- ExpectState state;
- Map prevMap = null;
- if (g_state != null)
- prevMap = g_state.getVars();
-
- int matchedWhere = result.beginOffset(0);
- String matchedText = result.toString(); // expect_out(0,string)
-
- // Unmatched upto end of match
- // expect_out(buffer)
- char[] chBuffer = input.getBuffer();
- String copyBuffer = new String(chBuffer, 0, result.endOffset(0) );
-
- List /* <String> */ groups = new ArrayList();
- for (int j = 1; j <= result.groups(); j++) {
- String group = result.group(j);
- groups.add( group );
- }
- state = new ExpectState(copyBuffer.toString(), matchedWhere, matchedText, pairIndex, groups, prevMap);
-
- return state;
- }
-
- /**
- * TODO
- *
- * @param pairs TODO
- * @return found something, and ran it. Calling function should use g_state to figure out what to do next
- */
- protected boolean runFirstMatch(List /* <PatternPair> */ pairs) throws Exception {
- MatchResult firstResult = null;
- PatternPair firstPair = null;
- int pairIndex = -1;
-
- ListIterator iter = pairs.listIterator();
- while (iter.hasNext()) {
- PatternPair pair = (PatternPair) iter.next();
- Pattern pattern = pair.getPattern();
-
- // reset input to begining
- input.setCurrentOffset(input.getBeginOffset());
-
- if (matcher.contains(input, pattern)) {
- MatchResult result = matcher.getMatch();
- if (firstResult == null || result.beginOffset(0) < firstResult.beginOffset(0)) {
- firstResult = result;
- firstPair = pair;
- pairIndex = iter.previousIndex(); // TODO confirm this
- }
- }
- }
-
- if (firstResult == null)
- return false; // didn't find anything
-
- // Found something
- //input's offset are illegal at this phase
- //input.setCurrentOffset(input.getBeginOffset());
- logger.trace("Using a result for " + firstPair.getPattern().getPattern());
- ExpectState state = prepareClosure(pairIndex, firstResult);
- Closure closure = firstPair.getClosure();
-
- try {
- if (closure != null)
- closure.run(state);
- } catch (Exception e) {
- throw e;
- } finally {
- g_state = state;
- }
- return true;
- }
-
- /**
- * A snapshot of the <code>Expect4j</code> state machine in its
- * current context.
- */
- private ExpectState g_state = null;
-
- /**
- * Returns the last match of the <code>Expect4j</code> state
- * machine. If no match is found, an empty {@link ExpectState}
- * class is returned.
- *
- * @return the last match found by <code>Expect4j</code>
- */
- public ExpectState getLastState() {
- // Very possibly null from an ONCE_CHANCE or initial state
- // But since the expected use is to call expect4j.getLastState().getMatch(), we want to help protect against NPE
- return (g_state != null) ? g_state : new ExpectState();
- }
-
- /**
- * Provide no default timeout.
- */
- public static final long TIMEOUT_NOTSET = -2;
-
- /**
- * Never timeout, wait forever.
- */
- public static final long TIMEOUT_FOREVER = -1;
-
- /**
- * Don't give timeout a chance. If nothing is found right away, stop checking.
- */
- public static final long TIMEOUT_NEVER = 0;
-
- /**
- * A default match timeout of 10 seconds.
- */
- public final static long TIMEOUT_DEFAULT = 10 * 1000;
-
- /**
- * The default match timeout, initialized to TIMEOUT_DEFAULT.
- */
- long defaultTimeout = TIMEOUT_DEFAULT;
-
- /**
- * Changes the default timeout value for the Expect4j instance.
- *
- * @param timeout the new timeout value in milliseconds
- * @TODO Check for valid values
- */
- public void setDefaultTimeout(long timeout) {
- logger.debug("Setting default timeout to " + timeout);
- defaultTimeout = timeout;
- }
-
- /**
- * TODO
- *
- * @param matches TODO
- * @return TODO
- */
- protected TimeoutMatch findTimeout(Match matches[]) {
- TimeoutMatch ourTimeout = null;
- for (int i = 0; i < matches.length; i++) {
- if (matches[i] instanceof TimeoutMatch)
- ourTimeout = (TimeoutMatch) matches[i];
- }
- /* TODO: candidate for removal?
- if( ourTimeout == null ) {
- // Have to create our own
- ourTimeout = new TimeoutMatch(null);
- }
- */
- return ourTimeout;
- }
-
- /**
- * TODO
- *
- * @param matches TODO
- * @return TODO
- */
- protected EofMatch findEof(Match matches[]) {
- EofMatch ourEof = null;
- for (int i = 0; i < matches.length; i++) {
- if (matches[i] instanceof EofMatch)
- ourEof = (EofMatch) matches[i];
- }
-
- if (ourEof == null) {
- // Have to create our own
- ourEof = new EofMatch();
- }
-
- return ourEof;
- }
-
- /**
- * Stops processing the reader/writer streams being managed by the
- * Expect4j instance.
- */
- public void close() {
- logger.debug("Stopping processing of the reader/writer streams by the Expect4j instance" + this);
- consumer.stop();
- logger.debug("Stopping the StreamPair, in which disconnect the TelnetClient" + this);
- pair.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import org.expect4j.matches.*;
-import java.text.StringCharacterIterator;
-import java.util.*;
-import org.apache.oro.text.regex.MalformedPatternException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import tcl.lang.*;
-
-/**
- * Register commands to support the Expect API
- *
- * Commands:
- * exp_continue
- * exp_internal 0;
- * expect
- * log_user 0;
- * send " ";
- * send -- "$command\r";
- * sleep
- * spawn
- * stty -echo;
- * stty echo;
- * timestamp
- *
- * Variables:
- * expect_out(1,string)
- * through
- * expect_out(5,string)
- * expect_out(buffer)
- * spawn_id
- */
-public class ExpectEmulation extends Extension {
- /**
- * Interface to the Java 2 platform's core logging facilities.
- */
- private static final Logger logger = LoggerFactory.getLogger(ExpectEmulation.class);
-
- //@Overrides
- public void init(Interp interp) {
- interp.createCommand("exp_continue", new ExpContinueCommand());
- interp.createCommand("exp_internal", new ExpInternalCommand());
- interp.createCommand("expect", new ExpectCommand());
- interp.createCommand("log_user", new LogUserCommand());
- interp.createCommand("send", new SendCommand());
- interp.createCommand("sleep", new SleepCommand());
- interp.createCommand("spawn", new SpawnCommand());
- interp.createCommand("stty", new SttyCommand());
- interp.createCommand("timestamp", new TimestampCommand());
-
- //interp.eval("rename subst ::tcl::subst");
- //interp.createCommand("subst", new tcl.lang.SubstCrCommand() );
- interp.createCommand("substcr", new tcl.lang.SubstCrCommand() );
-
- try {
- interp.pkgProvide("expect", "2.0"); // closest equivalent
- } catch (TclException te) {
- logger.warn(te.getMessage());
- }
- }
-
- /**
- * expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]
- *
- * TODO Fully integrate with Expect4j
- * TODO upvar the whole closure when running
- * TODO set expect_out array
- */
- public class ExpectCommand implements Command {
- void releaseClosures(Interp interp, Collection preserved) {
- Iterator iter = preserved.iterator();
- while( iter.hasNext() ) {
- TclObject tclCode = (TclObject) iter.next();
- tclCode.release();
- }
- }
-
- public void cmdProc(Interp interp, TclObject args[]) throws TclException {
- // Do not allow empty expect statement
- if (args.length != 2)
- throw new TclNumArgsException(interp, 0, args, "expect {[-opts] pat1 body1] ... [-opts] patn [bodyn]}");
-
- TclObject argArr = args[1];
- TclObject argv[] = TclList.getElements(interp, argArr);
-
- List /* <Pair> */ pairs = new ArrayList();
- int i=0;
- String arg;
- logger.debug("Looking at expect args");
- Match pair;
- Collection preserved = new ArrayList(argv.length - i);
-
- while( i < argv.length ) {
- arg = argv[i].toString();
- //log.info(i + " Looking at " + arg);
-
- if( arg.equals("timeout") ) {
- if( i + 1 >= argv.length )
- throw new TclNumArgsException(interp, i, argv, "expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]");
- TclObject tclCode = argv[++i];
- TclClosure closure = new TclClosure(interp, tclCode);
- pair = new TimeoutMatch( closure );
-
- logger.debug("Adding Timeout Match");
-
- pairs.add( pair );
- } else if( arg.equals("eof") ) {
- if( i + 1 >= argv.length )
- throw new TclNumArgsException(interp, i, argv, "expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]");
- TclObject tclCode = argv[++i];
- TclClosure closure = new TclClosure(interp, tclCode);
- pair = new EofMatch( closure );
-
- logger.debug("Adding Eof Match");
-
- pairs.add( pair );
- } else {
- TclObject patternObj;
- if( arg.startsWith("-") ) {
- // TODO do NumArgs check
- patternObj = argv[++i];
- } else {
- patternObj = argv[i];
- arg = "-gl"; // default to glob
- }
-
- String javaStr = patternObj.toString();
- /*
- StringBuffer hexString = new StringBuffer();
- for(int j=0; j < javaStr.length(); j++ ) {
- hexString.append( ((int) javaStr.charAt(j)) + ",");
- }
- log.info(i + " Characters " + hexString);
- */
- javaStr = javaStr.replaceAll("\\r", "\\\\r");
- javaStr = javaStr.replaceAll("\\n", "\\\\n");
- //interp.eval("subst -nobackslashes -nocommands {" + patternObj.toString() + "}", 0);
-
- Command substCmd = interp.getCommand("substcr");
- TclObject substArgv[] = new TclObject[] {
- TclString.newInstance("substcr"),
- TclString.newInstance("-nocommands"),
- TclString.newInstance("-nobackslashes"),
- patternObj
- };
- substCmd.cmdProc(interp, substArgv);
-
- TclObject substPatternObj = interp.getResult();
- String pattern = substPatternObj.toString();
-
- TclClosure closure = null;
- TclObject tclCode = null;
- if( i + 1 < argv.length ) {
- TclObject tclCodeDirect = argv[++i];
- tclCodeDirect.preserve();
- preserved.add(tclCodeDirect);
- tclCode = tclCodeDirect;
- }
- closure = new TclClosure(interp, tclCode);
-
- logger.debug(i + " Pattern Obj is >>" + javaStr + "<< and pattern is >>>" + pattern + "<<<");
- try {
- if( arg.startsWith("-re") ) {
- // In TCL \[ is used to tell TCL that this is not a nested command
- /* Need to support:
- * -re "User=(.+) Date=(.+) Time=(\[^\r]+)\r"
- * -re "\[Pp]assword: "
- * -re "/(\[a-z]+)/(\[0-9]+)/(\[a-z]+)\[\\$|>]"
- * -re "/(\[a-z]+)/(\[0-9]+)/(\[a-z]+)>"
- * -re "\\$ |....> "
- * -re "(\[^\n]*)\r\n"
- * -re "(\[^\r]*)\r\n"
- */
- pair = new RegExpMatch(pattern, closure);
- } else if ( arg.startsWith("-ex") )
- throw new TclException(interp, "Exact matches not supported yet");
- else if( arg.startsWith("-gl") ) {
- pair = new GlobMatch(pattern, closure);
- logger.debug(i + " Glob at regexp " + ((GlobMatch) pair).getPattern().getPattern() );
- } else {
- throw new TclException(interp, "Unknown type of pattern");
- }
- } catch(TclException te) {
- releaseClosures(interp, preserved);
- throw te;
- } catch(MalformedPatternException mpe) {
- releaseClosures(interp, preserved);
- throw new TclException(interp, "Invalid pattern: " + pattern);
- }
- pairs.add( pair );
- }
- i++;
-
- } // end while
-
- // Lookup Expect
- Expect4j expect4j = expStateCurrent(interp);
-
- // Timeout
- try {
- TclObject timeoutObj = interp.getVar("timeout", null, 0);
- int timeout = TclInteger.get(interp, timeoutObj);
- expect4j.setDefaultTimeout(timeout * 1000);
- }catch(Exception e) {
- expect4j.setDefaultTimeout( Expect4j.TIMEOUT_DEFAULT );
- }
-
- boolean isDebug = isExpDebug(interp);
- boolean isEcho = isEcho(interp);
- boolean isLogUser = isLogUser(interp);
- // TODO
- //expect4j.setDebugLevels(isDebug, isEcho, isLogUser);
-
- // Run Expect
- int ret;
- try {
- ret = expect4j.expect(pairs);
- } catch(TclException te) {
- throw te;
- } catch(Exception e) {
- throw new TclException(interp, e.getMessage() );
- } finally {
- releaseClosures(interp, preserved);
- }
-
- interp.setResult(ret);
- }
- }
-
- /* Commands in alphabetical order*/
-
- /**
- * exp_continue
- *
- * TODO Make calling Closure check for continue var
- */
- public class ExpContinueCommand implements Command {
- public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
- if (argv.length != 1)
- throw new TclNumArgsException(interp, 0, argv, "");
-
- setExpContinue(interp, true);
- // TODO immeadiately set debug level on Expect4j object
- }
- }
-
- /**
- * exp_internal [-f file] [-info] [0|1]
- *
- * TODO find out how isExpDebug would be called
- */
- public class ExpInternalCommand implements Command {
- public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
- if (argv.length != 2)
- throw new TclNumArgsException(interp, 0, argv, "[0|1]");
-
- String arg = argv[1].toString();
- if( arg.equals("1") )
- setExpDebug(interp, true);
- else if( arg.equals("0") )
- setExpDebug(interp, false);
- else
- throw new TclNumArgsException(interp, 0, argv, "[0|1]");
- }
- }
-
- /**
- * log_user [0|1]
- *
- * TODO find out how isLogUser would be called
- */
- public class LogUserCommand implements Command {
- public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
- if (argv.length != 2)
- throw new TclNumArgsException(interp, 0, argv, "[0|1]");
-
- String arg = argv[1].toString();
- if( arg.equals("1") )
- setLogUser(interp, true);
- else if( arg.equals("0") )
- setLogUser(interp, false);
- else
- throw new TclNumArgsException(interp, 0, argv, "[0|1]");
-
- // TODO immeadiately set debug level on Expect4j object
- }
- }
-
- /**
- * Send
- */
- public class SendCommand implements Command {
- public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
- logger.debug("Send Command arg # " + argv.length);
- if (argv.length == 1)
- throw new TclNumArgsException(interp, 1, argv, "[-flags] [--] string");
-
- boolean checkingFlags = true;
- int i=1;
- String arg = null;
- for(; i < argv.length; i++) {
- arg = argv[i].toString();
- if( checkingFlags && arg.equals("--") ) {
- checkingFlags = false;
- continue;
- }
- // skip flags
- if( checkingFlags && arg.startsWith("-") )
- continue;
- }
-
- // Compensate for the added i++
- if (i - 1 == argv.length)
- throw new TclNumArgsException(interp, 1, argv, "[-flags] [--] string");
-
- //arg = interp.convertStringCRLF(arg); // TODO confirm is CRLF removal is necessary
- String pattern1 = "\r(?=[^\n])";
- String pattern2 = "\r$";
- arg = arg.replaceAll(pattern1, org.apache.commons.net.SocketClient.NETASCII_EOL);
- arg = arg.replaceAll(pattern2, org.apache.commons.net.SocketClient.NETASCII_EOL);
-
- Expect4j expect4j = expStateCurrent(interp);
-
-
- try {
- expect4j.send(arg);
- }catch(Exception ioe) {
- throw new TclException(interp, "Unable to send " + arg);
- }
-
- if( isEcho(interp) )
- //System.out.println(arg);
- logger.debug(arg);
- }
- }
-
- /**
- * sleep seconds
- */
- public class SleepCommand implements Command {
- public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
- if (argv.length > 2)
- throw new TclNumArgsException(interp, 0, argv, "seconds");
-
- int seconds = TclInteger.get(interp, argv[1]);
- try {
- Thread.sleep( seconds * 1000 );
- } catch(InterruptedException e) {
- }
- }
- }
-
- /**
- * spawn [args] program [args]
- * Called with possible local paths, like C:\Windows\ssh.exe.
- */
- public class SpawnCommand implements Command, VarTrace {
- public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
- if (argv.length == 1)
- throw new TclNumArgsException(interp, 0, argv, "[args] program [args]");
-
- // Skip the -args, e.g. -console, -ignore, -leaveopen, etc
- int i = 1;
- while( i < argv.length && argv[i].toString().indexOf('-') == 0 ) {
- i++;
- }
-
- if( i == argv.length ) // missing program arg
- throw new TclNumArgsException(interp, i, argv, "[args] program [args]");
- String program = argv[i++].toString().trim();
-
- // Determine if we're running ssh or telnet and create Pair
- Expect4j expect4j;
- if( program.indexOf("ssh") != -1 ) {
- // SSH
- // Command will look like:
- // spawn $path(ssh) -l fieldsvc $chassis(scpAddr)
- String username = null;
- String password = null;
- while( argv[i].toString().indexOf('-') == 0) {
- // process arg
- logger.debug("ssh arg: " + argv[i].toString() );
- if( argv[i].toString().equals("-l") && i + 1 < argv.length - 1) {
- username = argv[++i].toString();
- }
- if( argv[i].toString().equals("-P") && i + 1 < argv.length - 1) {
- password = argv[++i].toString();
- }
- i++;
- }
-
- if( username == null)
- throw new TclException(interp, "Username needs to be provided");
- else
- logger.debug("Username: " + username);
-
- if( i >= argv.length )
- throw new TclNumArgsException(interp, i - 1, argv, "[-l username] [-P password] hostname");
- String hostname = argv[i].toString().trim();
-
- try {
- expect4j = ExpectUtils.SSH( hostname, username, password );
- }catch(Exception e) {
- e.printStackTrace();
- throw new TclException(interp, "Unable to connect using SSH");
- }
- } else if( program.indexOf("telnet") == 0 ) {
- // Telnet
- // spawn telnet $chassis(scpAddr) 7653
- String hostname = null;
- String portStr = null;
- if( i >= argv.length )
- throw new TclNumArgsException(interp, i, argv, "hostname port" );
- hostname = argv[i++].toString().trim();
-
- if( i < argv.length )
- portStr = argv[i++].toString().trim();
-
- int port = 23;
- if( portStr != null ) {
- try {
- port = Integer.parseInt(portStr);
- }catch(NumberFormatException e) {
- throw new TclException(interp, "Unable to parse the port number");
- }
- }
-
- try {
- expect4j = ExpectUtils.telnet( hostname, port);
- }catch(Exception e) {
- throw new TclException(interp, "Unable to connect using Telnet");
- }
- } else {
- // Unsupported
- String[] cmdarray;
- int cmdidx = 0;
- int addlargs = argv.length - i + 1;
-
- // Guess OS
- String OS = System.getProperty("os.name").toLowerCase();
- if (OS.indexOf("windows 9") > -1) {
- // Windows 98
- cmdarray = new String[ addlargs + 2];
- cmdarray[cmdidx++] = "command.com";
- cmdarray[cmdidx++] = "/c";
- } else if ( OS.indexOf("windows") > -1 ) {
- // NT
- cmdarray = new String[ addlargs + 2];
- cmdarray[cmdidx++] = "cmd.exe";
- cmdarray[cmdidx++] = "/c";
- } else {
- // Unix
- cmdarray = new String[ addlargs];
- }
-
- // Append actual command and its args
- cmdarray[cmdidx++] = program;
- for(;i < argv.length; i++) {
- cmdarray[cmdidx++] = argv[i].toString().trim();
- }
-
- try {
- Process process = Runtime.getRuntime().exec(cmdarray);
- expect4j = new Expect4j(process);
- }catch(Exception e) {
- throw new TclException(interp, "Unable to start arbitary process");
- }
- }
-
- // Load and store lastSpawnId
- int nextId = 1;
- IntegerAssocData lastSpawnId = (IntegerAssocData) interp.getAssocData("lastSpawnId");
- if( lastSpawnId != null )
- nextId = lastSpawnId._i.intValue() + 1;
- lastSpawnId = new IntegerAssocData(nextId);
- interp.setAssocData("lastSpawnId", lastSpawnId);
-
- // register spawn_id with list
- MapAssocData spawnIds = (MapAssocData) interp.getAssocData("spawnIds");
- if( spawnIds == null ) {
- spawnIds = new MapAssocData();
- }
-
- String spawnId = lastSpawnId._i.toString();
- logger.debug("Putting id in " + spawnId);
- spawnIds.put( spawnId, expect4j );
- interp.setAssocData("spawnIds", spawnIds);
-
- // register spawn_id with interp
- TclObject spawnIdObj = TclInteger.newInstance( nextId );
- interp.setVar("spawn_id", spawnIdObj, 0);
- interp.traceVar("spawn_id", this, 0);
-
- interp.setResult(spawnIdObj);
- }
-
- public void traceProc(Interp interp, String name1, String name2, int flags) {
- logger.debug("Tracing");
- if ( (flags & TCL.TRACE_DESTROYED) != 0 )
- logger.warn("Trace Destroyed");
- if ( (flags & TCL.INTERP_DESTROYED) != 0 )
- logger.warn("Interp Destroyed");
- }
- }
-
- /**
- * timestamp [-seconds NNN] [-gmt] [-format format]
- *
- * TODO support formattings
- */
- public class TimestampCommand implements Command {
- public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
- if (argv.length > 1)
- throw new TclNumArgsException(interp, 0, argv, "");
-
- long epoch = new Date().getTime();
- if( epoch >= Double.MAX_VALUE )
- throw new TclException(interp, "Epoch is too large to convert to double");
-
- double epochd = new Long(epoch).doubleValue();
- TclObject result = TclDouble.newInstance(epochd);
- interp.setResult( result );
- }
- }
-
- /**
- * stty [-echo|echo]
- *
- * Only called in ask, which shouldn't be called in automated script mode
- */
- public class SttyCommand implements Command {
- public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
- if (argv.length > 2)
- throw new TclNumArgsException(interp, 0, argv, "[echo|-echo]");
-
- String cmd = argv[1].toString();
- logger.debug("stty cmd is " + cmd);
- if( cmd.equals("echo") )
- setEcho(interp, true);
- else if( cmd.equals("-echo") )
- setEcho(interp, false);
- else
- throw new TclException(interp, "Only echo is supported");
-
- // TODO immeadiately set debug level on Expect4j object
-
- }
- }
-
- public class IntegerAssocData implements AssocData {
- public Integer _i;
- public IntegerAssocData(int value) {
- _i = new Integer(value);
- }
-
- public IntegerAssocData(String s) {
- _i = new Integer(s);
- }
-
- public void disposeAssocData(Interp interp) {
- }
- }
-
- public class MapAssocData extends HashMap implements AssocData {
- public void disposeAssocData(Interp interp) {
- }
- }
-
- /* TODO change return type to Expect4j */
- public static Expect4j expStateCurrent(Interp interp) throws TclException {
- TclObject spawnObj = interp.getVar("spawn_id", 0); // confirm that this works and we don't need TCL.NAMESPACE_ONLY
-
- Map spawnIds = (Map) interp.getAssocData("spawnIds");
- if( spawnIds == null )
- throw new TclException(interp, "spawn not called yet");
-
- String spawnId = spawnObj.toString();
- if( !spawnIds.containsKey(spawnId) )
- throw new TclException(interp, "Unable to find spawn_id of " + spawnId);
-
- Expect4j expect4j = (Expect4j) spawnIds.get(spawnId);
- if( expect4j == null )
- throw new TclException(interp, "Unable to find Expect context from " + spawnId);
-
- return expect4j;
- }
-
- public static boolean isVar(Interp interp, String varname) throws TclException {
- TclObject obj = null;
- try {
- obj = interp.getVar(varname, null, TCL.GLOBAL_ONLY);
- }catch(Exception e) {
- return false;
- }
-
- if ( obj == null) {
- return false;
- }
-
- return TclBoolean.get(interp, obj);
- }
- public static void setBooleanVar(Interp interp, String varname, boolean value) throws TclException {
- if( isVar(interp, varname) == value)
- return;
-
- TclObject obj = TclBoolean.newInstance(value);
- logger.debug("Setting " + varname + " to " + Boolean.toString(value) );
- interp.setVar(varname, obj, TCL.GLOBAL_ONLY);
- }
-
- public static boolean isEcho(Interp interp) throws TclException {
- return isVar(interp, "exp_tty_echo");
- }
- public static void setEcho(Interp interp, boolean setEcho) throws TclException {
- setBooleanVar(interp, "exp_tty_echo", setEcho);
- }
-
- public static boolean isLogUser(Interp interp) throws TclException {
- return isVar(interp, "exp_log_user");
- }
- public static void setLogUser(Interp interp, boolean setLogUser) throws TclException {
- setBooleanVar(interp, "exp_log_user", setLogUser);
- }
-
- public static boolean isExpDebug(Interp interp) throws TclException {
- return isVar(interp, "exp_debug");
- }
- public static void setExpDebug(Interp interp, boolean setExpDebug) throws TclException {
- setBooleanVar(interp, "exp_debug", setExpDebug);
- }
-
- public static boolean isExpContinue(Interp interp) throws TclException {
- return isVar(interp, "exp_continue_set");
- }
- public static void setExpContinue(Interp interp, boolean setExpContinue) throws TclException {
- setBooleanVar(interp, "exp_continue_set", setExpContinue);
- }
-
- public static String escape(final String value) {
- String raw = value;
- boolean isString = false;
-
- if( value.indexOf('"') == 0 && value.lastIndexOf('"') == value.length() - 1) {
- isString = true;
- raw = value.substring(1, value.length() - 1);
- }
-
- final StringBuffer result = new StringBuffer();
-
- StringCharacterIterator iterator = new StringCharacterIterator(raw);
- char character = iterator.current();
- while (character != StringCharacterIterator.DONE ){
- /*
- * All literals need to have backslashes doubled.
- * &;`'"|*?~<>^()[]{}$\
- */
- switch( character ) {
- case '&':
- case ';':
- case '\'':
- case '"':
- case '|':
- case '*':
- case '?':
- case '~':
- case '<':
- case '>':
- case '^':
- case '(':
- case ')':
- case '[':
- case ']':
- case '{':
- case '}':
- case '$':
- case '\\': result.append("\\");
- default: result.append(character);
- }
- character = iterator.next();
- }
- String clean = result.toString();
- if( isString )
- clean = '"' + clean + '"';
-
- return clean;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.util.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A container that represents a snapshot of the {@link Expect4j} state
- * machine for a given match. This container is typically used in
- * conjunction with {@link Closure}s, but may also be used with {@link
- * Expect4j#getLastState}.
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class ExpectState {
- /**
- * Interface to the Java 2 platform's core logging facilities.
- */
- private static final Logger logger = LoggerFactory.getLogger(ExpectState.class);
-
- /**
- * Creates an <code>ExpectState</code> instance for a successful
- * match. This instance is mostly immutable once created.
- *
- * @param buffer the entire reader buffer at the time of the match
- * @param matchedWhere the offset of the beginning of the match in
- * the buffer
- * @param match the exact match found
- * @param pairIndex TODO
- * @param groups a list of submatches, if defined in the match
- * pattern
- * @param prevMap a <code>Map</code> of the variables previously set
- * by {@link Closure}s
- */
- public ExpectState(String buffer, int matchedWhere, String match, int pairIndex, List groups, Map prevMap) {
- this(pairIndex, buffer, prevMap);
- this.matchedWhere = matchedWhere;
- this.match = match;
- this.groups = groups;
- }
-
- /**
- * Creates an <code>ExpectState</code> instance for times when a
- * {@link Closure} is being run but there isn't a corresponding
- * match. This instance is mostly immutable once created.
- */
- public ExpectState() {
- this(-1, null, null);
- }
-
- /**
- * Creates an <code>ExpectState</code> instance for a successful
- * match. This instance is mostly immutable once created.
- *
- * @param pairIndex TODO
- * @param buffer the entire reader buffer at the time of the match
- * @param prevMap a <code>Map</code> of the variables previously set
- * by {@link Closure}s
- */
- public ExpectState(int pairIndex, String buffer, Map prevMap) {
- this.buffer = buffer;
- this.matchedWhere = -1;
- this.match = null;
- this.pairIndex = pairIndex;
- this.groups = null;
- shouldContinue = false;
- shouldResetTimer = false;
-
- vars = new HashMap();
- if (prevMap != null)
- vars.putAll(prevMap);
- }
-
- /**
- * The offset, relative to the beginning of {@link
- * ExpectState#buffer}, where the match begins.
- */
- protected int matchedWhere;
-
- /**
- * Returns the offset into the buffer where the match begins.
- *
- * @return the offset of the match in the buffer
- */
- public int getMatchedWhere() {
- return matchedWhere;
- }
-
- /**
- * All text that generated a match while processing the buffer.
- */
- protected String match;
-
- /**
- * Returns all text found in the buffer that generated the match.
- * This is equivalent to Expect's <code>expect_out(0,string)</code>.
- *
- * @return all matching text in the buffer
- */
- public String getMatch() {
- return match;
- }
-
- /**
- * A list of submatches based on the entire match.
- */
- protected List /* <String> */ groups;
-
- /**
- * Returns the specific submatch based on index (1-based). This is
- * equivalent to Expect's <code>expect_out(x,string)</code>.
- */
- public String getMatch(int groupnum) {
- if (groupnum == 0)
- return getMatch();
- else if (groupnum > groups.size())
- return null;
-
- return (String) groups.get(groupnum - 1);
- }
-
- /**
- * TODO
- */
- protected int pairIndex;
-
- /**
- * TODO
- *
- * @return TODO
- */
- public int getPairIndex() {
- return pairIndex;
- }
-
- /**
- * The entire reader buffer at the time of the match.
- */
- protected String buffer;
-
- /**
- * Returns the entire reader buffer. This is equivalent to Expect's
- * <code>expect_out(buffer)</code>.
- *
- * @return the entire reader buffer.
- */
- public String getBuffer() { return buffer; }
-
- /**
- * Sets the reader buffer.
- *
- * @param buffer the contents of the buffer
- */
- public void setBuffer(String buffer) {
- this.buffer = buffer;
- }
-
- /**
- * A flag to indicate whether the {@link Expect4j} state machine
- * should continue to seek additional matches.
- */
- protected boolean shouldContinue;
-
- /**
- * Returns whether the {@link Expect4j} state machine should
- * continue to seek additional matches after this one.
- *
- * @return <code>true</code> if the state machine should seek
- * additional matches, <code>false</code> if it should stop
- * with this one
- */
- public boolean shouldContinue() { return shouldContinue; }
-
- /**
- * Instructs the {@link Expect4j} state machine to continue to seek
- * additional matches after this one. This is equivalent to
- * Expect's <code>exp_continue -continue_timer</code>.
- *
- * @see ExpectState#exp_continue_reset_timer
- */
- public void exp_continue() {
- shouldContinue = true;
- }
-
- /**
- * A flag to indicate whether the {@link Expect4j} state machine
- * should reset its timer to avoid a timeout.
- */
- protected boolean shouldResetTimer; // TODO prevent closure from setting
-
- /**
- * Returns whether the {@link Expect4j} state machine should reset
- * its timeout timer after processing this match.
- *
- * @return <code>true</code> if the timer should be reset,
- * <code>false</code> if the timer should be allowed to
- * continue as-is
- */
- public boolean shouldResetTimer() {
- return shouldResetTimer;
- }
-
- /**
- * Instructs the {@link Expect4j} state machine to continue to seek
- * additional matches after this one <i>and</i> to reset the timeout
- * timer. This is equivalent to Expect's <code>exp_continue</code>.
- *
- * @see ExpectState#exp_continue
- */
- public void exp_continue_reset_timer() {
- shouldContinue = true;
- shouldResetTimer = true;
- }
-
- /* Closure Variables */
-
- /**
- * A map of key/value pairs that can be set during execution of a
- * {@link Closure} and accessed from outside the {@link Expect4j}
- * context. This list is constantly appended by each
- * <code>Closure</code> executed, so the final
- * <code>ExpectState</code> instance that is retrieved using {@link
- * Expect4j#getLastState} has the whole list.
- * <p>
- * This mechanism is provided as a way of emulating Tcl's natural
- * closure/scope behavior, which Java doesn't allow. In Tcl,
- * closures can reference outside variables directly. In Java,
- * closures can only reference outside variables if the variables
- * have been declared <code>final</code>. This use of
- * <code>final</code> presents certain challenges in performing
- * multiple matches with the same <code>Closure</code> block,
- * because only the first execution would alow the variable to be
- * set. Through this alternate mechanism, each execution can simply
- * add or manipulate the key/value pairs as desired.
- * <p>
- * Note that this mechanism is <i>in addition to</i> the use of a
- * <code>final</code> buffer (such as <code>StringBuffer</code>),
- * which may be more appropriate for certain cases.
- */
- protected Map vars;
-
- /**
- * Adds a key/value pair from a {@link Closure} context.
- *
- * @param key the name used to reference this variable
- * @param value the value stored in the variable for the key
- */
- public void addVar(String key, Object value) {
- vars.put(key, value);
- }
-
- /**
- * Returns the value for the given key.
- *
- * @param key the name used to reference the variable desired
- * @return the value stored in the variable for the key
- */
- public Object getVar(String key) {
- return vars.get(key);
- }
-
- /**
- * Returns the whole list of variables.
- *
- * @return the whole list of variables
- */
- Map getVars() {
- return vars;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import com.jcraft.jsch.*;
-import org.expect4j.matches.*;
-import java.io.*;
-import java.net.Socket;
-import java.util.Hashtable;
-import java.util.logging.*;
-import org.apache.commons.net.io.*;
-import org.apache.commons.net.telnet.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utilities functions to help access the Expect4J library in the most
- * common ways. This functions can be used directly or used as a model
- * to copy for your own uses.
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public abstract class ExpectUtils {
- /**
- * Interface to the Java 2 platform's core logging facilities.
- */
- private static final Logger logger = LoggerFactory.getLogger(ExpectUtils.class);
-
- /**
- * Creates an HTTP client connection to a specified HTTP server and
- * returns the entire response. This function simulates <code>curl
- * http://remotehost/url</code>.
- *
- * @param remotehost the DNS or IP address of the HTTP server
- * @param url the path/file of the resource to look up on the HTTP
- * server
- * @return the response from the HTTP server
- * @throws Exception upon a variety of error conditions
- */
- public static String Http(String remotehost, String url) throws Exception {
- Socket s = null;
- s = new Socket(remotehost, 80);
- logger.debug("Connected to " + s.getInetAddress().toString() );
-
- if (false) {
- // for serious connection-oriented debugging only
- PrintWriter out = new PrintWriter(s.getOutputStream(), false);
- BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
-
- //System.out.println("Sending request");
- out.print("GET " + url + " HTTP/1.1\r\n");
- out.print("Host: " + remotehost + "\r\n");
- out.print("Connection: close\r\n");
- out.print("User-Agent: Expect4j\r\n");
- out.print("\r\n");
- out.flush();
- //System.out.println("Request sent");
-
- //System.out.println("Receiving response");
- String line;
- while ((line = in.readLine()) != null)
- //System.out.println(line);
- //System.out.println("Received response");
- if (line == null)
- System.exit(0);
- }
-
- Expect4j expect = new Expect4j(s);
-
- logger.debug("Sending HTTP request for " + url);
- expect.send("GET " + url + " HTTP/1.1\r\n");
- expect.send("Host: " + remotehost + "\r\n");
- expect.send("Connection: close\r\n");
- expect.send("User-Agent: Expect4j\r\n");
- expect.send("\r\n");
-
- logger.debug("Waiting for HTTP response");
- String remaining = null;
- expect.expect(new Match[] {
- new RegExpMatch("HTTP/1.[01] \\d{3} (.*)\n?\r", new Closure() {
- public void run(ExpectState state) {
- logger.trace("Detected HTTP Response Header");
-
- // save http code
- String match = state.getMatch();
- String parts[] = match.split(" ");
-
- state.addVar("httpCode", parts[1]);
- state.exp_continue();
- }
- }),
- new RegExpMatch("Content-Type: (.*\\/.*)\r\n", new Closure() {
- public void run(ExpectState state) {
- logger.trace("Detected Content-Type header");
- state.addVar("contentType", state.getMatch() );
- state.exp_continue();
- }
- }),
- new EofMatch( new Closure() { // should cause entire page to be collected
- public void run(ExpectState state) {
- logger.trace("Found EOF, done receiving HTTP response");
- }
- }), // Will cause buffer to be filled up till end
- new TimeoutMatch(10000, new Closure() {
- public void run(ExpectState state) {
- logger.trace("Timeout waiting for HTTP response");
- }
- })
- });
-
- remaining = expect.getLastState().getBuffer(); // from EOF matching
-
- String httpCode = (String) expect.getLastState().getVar("httpCode");
-
- String contentType = (String) expect.getLastState().getVar("contentType");
-
- s.close();
-
- return remaining;
- }
-
- /**
- * Creates an SSH session to the given server on TCP port 22 using
- * the provided credentials. This is equivalent to Expect's
- * <code>spawn ssh $hostname</code>.
- *
- * @param hostname the DNS or IP address of the remote server
- * @param username the account name to use when authenticating
- * @param password the account password to use when authenticating
- * @throws Exception on a variety of errors
- */
- public static Expect4j SSH(String hostname, String username, String password) throws Exception {
- return SSH(hostname, username, password, 22);
- }
-
- public static Expect4j SSH(String hostname, String username, String password, int port) throws Exception {
- logger.debug("Creating SSH session with " + hostname + ":" + port + " as " + username);
-
- JSch jsch = new JSch();
-
- //jsch.setKnownHosts("/home/foo/.ssh/known_hosts");
-
- Session session=jsch.getSession(username, hostname, port);
- if (password != null) {
- logger.trace("Setting the Jsch password to the one provided (not shown)");
- session.setPassword(password);
- }
-
- java.util.Hashtable config = new java.util.Hashtable();
- config.put("StrictHostKeyChecking", "no");
- session.setConfig(config);
- session.setDaemonThread(true);
- session.connect(3 * 1000); // making a connection with timeout.
-
- ChannelShell channel = (ChannelShell) session.openChannel("shell");
-
- //channel.setInputStream(System.in);
- //channel.setOutputStream(System.out);
-
- channel.setPtyType("vt102");
-
- Hashtable env=new Hashtable();
- //env.put("LANG", "ja_JP.eucJP");
- channel.setEnv(env);
-
- Expect4j expect = new Expect4j(channel.getInputStream(), channel.getOutputStream());
-
- channel.connect(5 * 1000);
-
- return expect;
- }
-
- /**
- * TODO Simulate "Could not open connection to the host, on port...."
- * TODO Simulate "Connection refused"
- */
- public static Expect4j telnet(String hostname, int port) throws Exception {
- // This library has trouble with EOF
- final TelnetClient client = new TelnetClient();
-
- TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, true);
- EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
- SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(false, false, false, false);
- client.addOptionHandler( ttopt );
- client.addOptionHandler( echoopt );
- client.addOptionHandler( gaopt );
-
- client.connect(hostname, port);
- InputStream is = new FromNetASCIIInputStream( client.getInputStream() ); // null until client connected
- OutputStream os = new ToNetASCIIOutputStream( client.getOutputStream() );
-
- StreamPair pair = new StreamPair(is, os) {
- public void close() {
- //super.close();
- try {
- if (client != null)
- client.disconnect();
- }catch(IOException ioe) {
-
- }
- }
- };
-
-
- /*
- URL url=new URL("telnet", hostname, port, "", new thor.net.URLStreamHandler());
- final URLConnection urlConnection=url.openConnection();
- urlConnection.connect();
- if (urlConnection instanceof TelnetURLConnection) {
- ((TelnetURLConnection)urlConnection).setTelnetTerminalHandler(new SimpleTelnetTerminalHandler());
- }
- OutputStream os=urlConnection.getOutputStream();
- InputStream is=urlConnection.getInputStream();
-
- StreamPair pair = new StreamPair(is, os) {
- public void close() {
- try { ((TelnetURLConnection)urlConnection).disconnect(); }catch(Exception e) { }
- }
- };
- */
- Expect4j expect4j = new Expect4j(pair);
-
- return expect4j;
- }
-
- /*
- class SimpleTelnetTerminalHandler extends DefaultTelnetTerminalHandler implements TelnetConstants {
- public void LineFeed() {
- System.out.print('\n');
- System.out.flush();
- }
- public void CarriageReturn() {
- System.out.print('\r');
- System.out.flush();
- }
- public void BackSpace() {
- System.out.print((char)BS);
- System.out.flush();
- }
- public void HorizontalTab() {
- System.out.print((char)HT);
- System.out.flush();
- }
- }
- */
-
- public static Expect4j spawn(String cmdLine) throws Exception {
- String[] cmdArgs = cmdLine.split(" ");
- return spawn(cmdArgs);
- }
-
- public static Expect4j spawn(String cmdArgs[]) throws Exception {
- Process process = Runtime.getRuntime().exec(cmdArgs);
- Expect4j expect = new Expect4j(process);
- return expect;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.io.Reader;
-import java.io.Writer;
-
-/**
- * TODO
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public interface IOPair {
- /**
- * Returns a {@link java.io.Reader} that accesses the input stream.
- *
- * @return a <code>Reader</code> for the input stream
- */
- public Reader getReader();
-
- /**
- * Returns a {@link java.io.Writer} that accesses the output stream.
- *
- * @return a <code>Writer</code> for the output stream
- */
- public Writer getWriter();
-
- /**
- * TODO
- */
- public void reset();
-
- /**
- * TODO
- */
- public void close();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-/**
- * Small bean to hold the results from a match. Maybe extends to hold
- * multiple match patterns. Existance of this object implies a match, to
- * show a no match use a null.
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class MatchFound {
- int posEndOfMatch; // to know where to cut off the buffer
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.*;
-import java.nio.channels.*;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * TODO
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public abstract class NioConsumer extends ConsumerImpl {
-
- /** Creates a new instance of NioConsumer */
- public NioConsumer(IOPair pair) throws Exception {
- super(pair);
-
- socketChannel = SocketChannel.open();
- socketChannel.configureBlocking(false);
- InetSocketAddress isa = new InetSocketAddress(host, port);
- socketChannel.connect(isa);
- selector = Selector.open();
- int interest = 0;
-
- if(socketChannel.isConnected())interest = SelectionKey.OP_READ;
- else if(socketChannel.isConnectionPending())interest = SelectionKey.OP_CONNECT;
-
- socketChannel.register(selector, interest);
- }
-
- abstract public void run();
- abstract public void waitForBuffer(long timeoutMilli);
- abstract public String pause();
- abstract public void resume(int offset);
-
-
- private String host = "localhost";
- private int port = 5001;
- private SocketChannel socketChannel;
- private Selector selector;
-/*
- public void run() {
- try {
-
- while(true) {
- int nn = selector.select();
- System.out.println("nn="+nn);
- Set keys = selector.selectedKeys();
- for(Iterator i = keys.iterator(); i.hasNext();) {
- SelectionKey key = (SelectionKey) i.next();
- i.remove();
- if (key.isConnectable()) {
- SocketChannel keyChannel = (SocketChannel) key.channel();
- System.out.println("Connected "+keyChannel.finishConnect());
- key.interestOps(SelectionKey.OP_READ);
- }
- if (key.isReadable()) {
- SocketChannel keyChannel = (SocketChannel) key.channel();
- String m = read(keyChannel);
- display(m);
- }
- }
- }
-
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
-
- public void send(final String m) {
- Thread t = new Thread(new Runnable() {
- public void run() {
- try {
- write(m, socketChannel);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- });
- t.start();
-
- }
- public static String read(SocketChannel channel) throws IOException {
-
- log("*** start READ");
- int n;
-
- ByteBuffer buffer = ByteBuffer.allocate(1024);
-
- while((n = channel.read(buffer)) > 0) {
- System.out.println(" adding "+n+" bytes");
- }
-
-
- log(" BUFFER REMPLI : "+buffer);
-
- buffer.flip();
-
- CharBuffer cb = dec.decode(buffer);
- log(" CHARBUFFER : "+cb);
-
-
- String m = cb.toString();
- log(" MESSAGE : "+m);
- log("*** end READ");
- //buffer.clear();
- return m;
- }
- public static void write(String m, SocketChannel channel) throws IOException {
-
- log("xxx start WRITE");
-
- CharBuffer cb = CharBuffer.wrap(m);
- log(" CHARBUFFER : "+cb);
-
- ByteBuffer buffer = enc.encode(cb);
- log(" BUFFER ALLOUE REMPLI : "+buffer);
-
- int n;
- while(buffer.hasRemaining()) {
- n = channel.write(buffer);
- }
- System.out.println(" REMAINING : "+buffer.hasRemaining());
- log("xxx end WRITE");
- }
- */
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Responsible for absorbing everything from stream and to maintain a buffer.
- *
- * TODO Rewrite with NIO
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class PollingConsumer extends ConsumerImpl {
- /**
- * Interface to the Java 2 platform's core logging facilities.
- */
- private static final Logger logger = LoggerFactory.getLogger(PollingConsumer.class);
-
- boolean dirtyBuffer;
- Boolean callerProcessing = Boolean.FALSE;
-
- boolean foundMore = false;
-
- public PollingConsumer(IOPair pair) {
- super(pair);
- dirtyBuffer = false;
- }
-
- /**
- * TODO Handle timeout of zero to expect, that shouldn't wait
- */
- public void run() {
- int length;
- char cs[] = new char[256];
- int ioErrorCount = 0;
- Reader reader = pair.getReader();
-
- logger.trace("Starting primary loop");
- while ( !stopRequested && !foundEOF && ioErrorCount < 4) {
- try {
- logger.trace("Checking ready");
- boolean ready = false;
- try {
- ready = reader.ready(); // will not block
- if( reader.markSupported() ) logger.trace("Mark Supported");
- } catch(Exception ioe) {
- // The Pipe most likely closed on us.
- logger.debug("Exception in PollingConsumer: " + ioe);
- foundEOF = true;
- break;
- }
-
- //if( !ready ) { ready = true; log.fine("Faking ready"); }
-
- if ( ready ) {
- logger.trace("Is Ready");
-
-
- // don't modify the buffer while processing is happening
- // written as while loop to prevent spurious interrupts
- synchronized(this) {
- while( callerProcessing.booleanValue() ) {
- logger.trace("Waiting for caller to finish");
- try {
- wait();
- } catch(InterruptedException ie) {
- logger.trace("Woken up early");
- continue;
- }
- }
-
- logger.trace("About to wait for buffer lock");
- synchronized(buffer) {
- length = reader.read(cs);
-
- if( length == -1 ) { //EOF
- logger.trace("Found the EOF");
- logger.trace("Current buffer: " + buffer.toString() );
- foundEOF = true;
- dirtyBuffer = true;
- break;
- }
-
- String print = new String(cs, 0, length);
- print = print.replaceAll("\n", "\\\\n");
- print = print.replaceAll("\r", "\\\\r");
- logger.trace("Appending >>>" + print + "<<<");
- buffer.append( cs, 0, length ); // thread safe
-
- logger.trace("Current Buffer: " + buffer.toString() );
- dirtyBuffer = true;
-
- /**
- * TODO Trim down buffer. This current method won't work if a resume comes in, since it's offset
- * will be invalid once this delete method runs
- *
- * // since we only added one char, we should only have to remove one
- * if( buffer.length() > BUFFERMAX )
- * buffer.delete(0, BUFFERMAX - buffer.length() );
- */
-
- logger.trace("Waking up who ever if listening");
- buffer.notify(); // seeing that we read something, wait people up
- }
- }
-
- } else {
- logger.trace("Not Ready, sleeping");
- try { Thread.sleep(500); } catch(InterruptedException ie) { }
- logger.trace("Done sleeping");
- //continue;
- }
- }catch(IOException ioe) {
- logger.warn("Exception in loop body: " + ioe);
- ioErrorCount++;
- //continue;
- }
- } // end while loop
-
-
- synchronized(buffer) {
- buffer.notify();
- }
- if( stopRequested ) {
- logger.debug("Stop Requested");
- pair.close();
- }
- if ( foundEOF )
- logger.debug("Found EOF to stop while loop");
- if( ioErrorCount >= 4 )
- logger.debug("ioErrorCount at " + ioErrorCount );
- logger.trace("Leaving primary loop");
- }
-
- /**
- * What is something came in between when we last checked and when this method is called
- */
- public void waitForBuffer(long timeoutMilli) {
- //assert(callerProcessing.booleanValue() == false);
-
- synchronized(buffer) {
- if( dirtyBuffer )
- return;
- if( !foundEOF() ) {
- logger.trace("Waiting for things to come in, or until timeout");
- try {
- if( timeoutMilli > 0 )
- buffer.wait(timeoutMilli);
- else
- buffer.wait();
- } catch(InterruptedException ie) {
- logger.trace("Woken up, while waiting for buffer");
- }
- // this might went early, but running the processing again isn't a big deal
- logger.trace("Waited");
- }
- }
- }
-
- public String pause() {
- // TODO mark offset, so that it can be trimmed by resume coming in later
- String currentBuffer;
- synchronized(this) { // stop consumer from continuing
- currentBuffer = buffer.toString();
- dirtyBuffer = false;
- callerProcessing = Boolean.TRUE;
- }
- return currentBuffer;
- }
-
- public void resume(int offset) {
-
- synchronized(this) {
- // if pause was called, then the main loop should be blocked callerProcessing,
- // and the buffer is safe.
- if( offset >= 0 ) {
- logger.trace("Moving buffer up by " + offset);
- StringBuffer smaller = buffer.delete(0, offset + 1);
- logger.trace("New size: " + buffer.length() + " vs " + smaller.length() );
- }
-
- callerProcessing = Boolean.FALSE; // should allow consumer to continue
- notify();
- }
- }
-
- /**
- * We have more input since wait started
- */
-
- public static void main(String args[]) throws Exception {
- final StringBuffer buffer = new StringBuffer("The lazy fox");
- Thread t1 = new Thread() {
- public void run() {
- synchronized(buffer) {
- buffer.delete(0,4);
- buffer.append(" in the middle");
- System.err.println("Middle");
- try { Thread.sleep(4000); } catch(Exception e) {}
- buffer.append(" of fall");
- System.err.println("Fall");
- }
- }
- };
- Thread t2 = new Thread() {
- public void run() {
- try { Thread.sleep(1000); } catch(Exception e) {}
- buffer.append(" jump over the fence");
- System.err.println("Fence");
- }
- };
- t1.start();
- t2.start();
-
- t1.join();
- t2.join();
- System.err.println(buffer);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.Writer;
-
-/**
- * TODO
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class StreamPair implements IOPair {
- Reader is;
- Writer os;
-
- /** Creates a new instance of ReaderConsumer */
- public StreamPair(InputStream is, OutputStream os ) {
- this.is = new InputStreamReader(is );
- this.os = new OutputStreamWriter( os );
- }
-
- public Reader getReader() {
- return is;
- }
-
- public Writer getWriter() {
- return os;
- }
-
- /**
- * TODO evaluate if this is even needed
- */
- public void reset() {
- try {
- is.reset();
- }catch(IOException ioe) {
- }
- }
-
- public void close() {
- try { is.close(); } catch(Exception e) { }
- try { os.close(); } catch(Exception e) { }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import java.io.*;
-
-/**
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class StringPair implements IOPair {
- StringBuffer outBuffer;
- StringReader is;
- StringWriter os;
-
- /** Creates a new instance of StringPair */
- public StringPair(String baseStr) {
- is = new StringReader(baseStr);
- os = new StringWriter();
- }
-
- public Reader getReader() { return is; }
- public Writer getWriter() { return os; }
-
- public String getResult() {
- os.flush();
- return os.getBuffer().toString();
- }
-
- /**
- * TODO evaluate if this is even needed
- */
- public void reset() {
- try {
- os.flush();
- os = new StringWriter();
- is.reset();
- }catch(IOException ioe) {
- }
- }
-
- public void close() {
- try { is.close(); } catch(Exception e) { }
- try { os.close(); } catch(Exception e) { }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j;
-
-import tcl.lang.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * TODO
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class TclClosure implements Closure {
- /**
- * Interface to the Java 2 platform's core logging facilities.
- */
- private static final Logger logger = LoggerFactory.getLogger(TclClosure.class);
-
- Interp interp;
- TclObject tclCode;
-
- /** Creates a new instance of TclClosure */
- public TclClosure(Interp interp, TclObject tclCode) {
- this.interp = interp;
- this.tclCode = tclCode;
- }
-
- /**
- * Establish certain variables in the TCL interp. These include:
- *
- * expect_out([1-5], string)
- * expect_out(buffer)
- */
- public void run(ExpectState state) throws Exception {
- int flags = 0; // TCL.NAMESPACE_ONLY
-
- // TODO Inject expect object, so that expect wrapper can access it
- // clear previous expect_out
- //interp.unsetVar("expect_out", flags);
-
- String buffer = state.getBuffer();
- logger.trace("Setting var expect_out(buffer) to " + buffer);
- interp.setVar("expect_out", "buffer", buffer, flags);
-
- int group = 0;
- while(true) {
- String match = state.getMatch(group);
- String index = group + ",string";
- group++;
- if( match == null )
- break;
- logger.trace("Setting var expect_out(" + index +") to " + match);
- interp.setVar("expect_out", index , match, flags);
- }
-
- ExpectEmulation.setExpContinue(interp, false);
-
- if( tclCode != null && tclCode.toString().length() > 0 ) {
- logger.debug("Running a tcl bit of code: " + tclCode.toString());
-
- try {
- interp.eval(tclCode, 0);
- } catch(TclException e) {
- logger.warn("Exception: " + e);
- throw new Exception( interp.getResult().toString(), e);
- }
- if( ExpectEmulation.isExpContinue(interp) ) {
- logger.info("Asked to continue");
- state.exp_continue();
- }
- }
- //interp.unsetVar("expect_out", flags);
-
- }
-
- public String toString() {
- if( tclCode != null)
- return tclCode.toString();
- return null;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j.matches;
-
-import org.expect4j.*;
-
-/**
- * TODO
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class EofMatch extends Match {
- public EofMatch(Closure closure) {
- super(closure);
- }
-
- public EofMatch() {
- super();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j.matches;
-
-import org.expect4j.*;
-import org.apache.oro.text.GlobCompiler;
-import org.apache.oro.text.regex.*;
-
-/**
- * Simulates "expect { -gl {..*} { code } }
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class GlobMatch extends RegExpMatch {
-
- /** Creates a new instance of RegExpMatch */
- public GlobMatch(String pattern, Closure closure) throws MalformedPatternException {
- super(pattern, closure);
- }
-
- public Pattern compilePattern(String patternStr) throws MalformedPatternException {
- int globOptions = GlobCompiler.DEFAULT_MASK | GlobCompiler.QUESTION_MATCHES_ZERO_OR_ONE_MASK;
- char [] patternCh = patternStr.toCharArray();
- String perl5PatternStr = GlobCompiler.globToPerl5(patternCh, globOptions);
-
- return super.compilePattern(perl5PatternStr);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j.matches;
-
-import org.expect4j.*;
-
-/**
- * TODO
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class Match {
-
- Closure closure;
-
- /** Creates a new instance of EofMatch */
- public Match(Closure closure) {
- this.closure = closure;
- }
-
- public Match() {
- this.closure = null;
- }
-
- public Closure getClosure() {
- return closure;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j.matches;
-
-import org.expect4j.*;
-import org.apache.oro.text.regex.*;
-
-/**
- *
- * @author justin
- */
-public abstract class PatternPair extends Match {
-
- String patternStr;
- Pattern pattern;
-
- /**
- * Creates a new instance of PatternPair
- */
- public PatternPair(String patternStr, Closure closure) throws MalformedPatternException {
- super(closure);
- this.patternStr = patternStr;
- pattern = compilePattern(patternStr);
- }
-
- abstract public Pattern compilePattern(String patternStr) throws MalformedPatternException;
-
- public Pattern getPattern() {
- return pattern;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j.matches;
-
-import org.expect4j.*;
-import org.apache.oro.text.regex.*;
-
-/**
- * Simulates "expect { -regexp {..*} { code } }
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class RegExpMatch extends PatternPair {
-
- /** Creates a new instance of RegExpMatch */
- public RegExpMatch(String patternStr, Closure closure) throws MalformedPatternException {
- super(patternStr, closure);
- }
-
- //TODO: removed static keyword, since Perl5Compiler is not threadsafe
- //
- protected Perl5Compiler compiler;
- public Perl5Compiler getCompiler() {
- if( compiler == null)
- compiler = new Perl5Compiler();
- return compiler;
- }
-
- public Pattern compilePattern(String patternStr) throws MalformedPatternException {
- Perl5Compiler compiler = getCompiler();
- return compiler.compile(patternStr, Perl5Compiler.DEFAULT_MASK|Perl5Compiler.SINGLELINE_MASK); // |Perl5Compiler.MULTILINE_MASK
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Justin Ryan
- * Copyright (c) 2013 Chris Verges <chris.verges@gmail.com>
- *
- * 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.expect4j.matches;
-
-import org.expect4j.*;
-
-/**
- *
- * @author Chris Verges
- * @author Justin Ryan
- */
-public class TimeoutMatch extends Match {
-
- long timeout;
-
- /**
- * Creates a new instance of TimeoutMatch with a default timeout of
- * ten seconds
- */
- public TimeoutMatch(Closure closure) {
- this(Expect4j.TIMEOUT_NOTSET, closure);
- }
-
- public TimeoutMatch(long milli, Closure closure) {
- super(closure);
- this.timeout = milli;
- }
-
- public long getTimeout() {
- return timeout;
- }
-
-}
+++ /dev/null
-/*
- * SubstCmd.java
- *
- * Copyright (c) 1997 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and
- * redistribution of this file, and for a DISCLAIMER OF ALL
- * WARRANTIES.
- *
- * RCS: @(#) $Id: SubstCmd.java,v 1.4 2005/07/22 04:47:25 mdejong Exp $
- *
- */
-
-package tcl.lang;
-
-import java.util.*;
-
-/**
- * This class implements the built-in "subst" command in Tcl. But it doesn't ignore carriage returns.
- */
-public class SubstCrCommand implements Command {
- static final private String validCmds[] = {
- "-nobackslashes",
- "-nocommands",
- "-novariables"
- };
-
- static final int OPT_NOBACKSLASHES = 0;
- static final int OPT_NOCOMMANDS = 1;
- static final int OPT_NOVARS = 2;
-
- /**
- * This procedure is invoked to process the "subst" Tcl command.
- * See the user documentation for details on what it does.
- *
- * @param interp the current interpreter.
- * @param argv command arguments.
- * @exception TclException if wrong # of args or invalid argument(s).
- */
-
- public void cmdProc(Interp interp, TclObject argv[])
- throws TclException {
- int currentObjIndex, len, i;
- int objc = argv.length - 1;
- boolean doBackslashes = true;
- boolean doCmds = true;
- boolean doVars = true;
- StringBuffer result = new StringBuffer();
- String s;
- char c;
-
- for (currentObjIndex = 1; currentObjIndex < objc; currentObjIndex++) {
- if (!argv[currentObjIndex].toString().startsWith("-")) {
- break;
- }
- int opt = TclIndex.get(interp, argv[currentObjIndex],
- validCmds, "switch", 0);
- switch (opt) {
- case OPT_NOBACKSLASHES:
- doBackslashes = false;
- break;
- case OPT_NOCOMMANDS:
- doCmds = false;
- break;
- case OPT_NOVARS:
- doVars = false;
- break;
- default:
- throw new TclException(interp,
- "SubstCrCmd.cmdProc: bad option " + opt
- + " index to cmds");
- }
- }
- if (currentObjIndex != objc) {
- throw new TclNumArgsException(interp, currentObjIndex, argv,
- "?-nobackslashes? ?-nocommands? ?-novariables? string");
- }
-
- /*
- * Scan through the string one character at a time, performing
- * command, variable, and backslash substitutions.
- */
-
- s = argv[currentObjIndex].toString();
- len = s.length();
- i = 0;
- while (i < len) {
- c = s.charAt(i);
-
- if ((c == '[') && doCmds) {
- ParseResult res;
- try {
- interp.evalFlags = Parser.TCL_BRACKET_TERM;
- interp.eval(s.substring(i + 1, len));
- TclObject interp_result = interp.getResult();
- interp_result.preserve();
- res = new ParseResult(interp_result,
- i + interp.termOffset);
- } catch (TclException e) {
- i = e.errIndex + 1;
- throw e;
- }
- i = res.nextIndex + 2;
- result.append( res.value.toString() );
- res.release();
- /**
- * Removed
- (ToDo) may not be portable on Mac
- } else if (c == '\r') {
- i++;
- */
- } else if ((c == '$') && doVars) {
- ParseResult vres = Parser.parseVar(interp,
- s.substring(i, len));
- i += vres.nextIndex;
- result.append( vres.value.toString() );
- vres.release();
- } else if ((c == '\\') && doBackslashes) {
- BackSlashResult bs = Interp.backslash(s, i, len);
- i = bs.nextIndex;
- if (bs.isWordSep) {
- break;
- } else {
- result.append( bs.c );
- }
- } else {
- result.append( c );
- i++;
- }
- }
-
- interp.setResult(result.toString());
- }
-}
+++ /dev/null
-/*\r
- * ExpectUtilsTelnetTest.java\r
- * JUnit based test\r
- *\r
- * Created on March 16, 2007, 9:42 AM\r
- */\r
-\r
-package org.expect4j;\r
-\r
-import junit.framework.*;\r
-import org.expect4j.matches.*;\r
-\r
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;\r
-/**\r
- *\r
- * @author justin\r
- */\r
-public class ExpectUtilsTelnetTest extends TestCase {\r
- private static final Logger logger = LoggerFactory.getLogger(Expect4j.class);\r
- public ExpectUtilsTelnetTest(String testName) {\r
- super(testName);\r
- testTelnetRounds();\r
- }\r
-\r
- protected void setUp() throws Exception {\r
- }\r
-\r
- protected void tearDown() throws Exception {\r
- }\r
-\r
- /*public void testTelnetSwitch() throws Exception {\r
- \r
- }*/\r
-\r
- public void testTelnetRounds() throws Exception {\r
- System.out.println("testTelnetRounds");\r
- for(int i = 0; i < 10; i++){\r
- System.out.println("round " + i);\r
- testTelnet();\r
- //goSleep();\r
- }\r
- }\r
- private void goSleep(){\r
- try
- {
- Thread.sleep(5000);\r
- }
- catch(Exception e1){
- logger.info("ERROR: ExpectHandler: goSleep(): exception: " + e1);
- }
- }\r
- /*public*/private void testTelnet() throws Exception {\r
- System.out.println("testTelnet");\r
- \r
- String hostname = "192.168.0.33";\r
- final String username = "admin";\r
- final String password = "password";\r
- \r
- if( hostname.equals("hostname") ) return; // fill in hostname, username,password.\r
- \r
- final Expect4j expect = ExpectUtils.telnet(hostname, 23);\r
- expect.setDefaultTimeout(/*Expect4j.TIMEOUT_FOREVER*/5000);\r
- \r
- expect.expect( new Match[] {\r
- new GlobMatch("UserName:"/*"login: "*/, new Closure() {\r
- public void run(ExpectState state) {\r
- try { expect.send(username + "\r"); } catch(Exception e) { /*Expect4j.log.warning*/logger.info(e.getMessage() ); }\r
- state.addVar("sentUsername", Boolean.TRUE);\r
- state.exp_continue();\r
- }\r
- }),\r
- /*new GlobMatch("Last login: ", new Closure() {\r
- public void run(ExpectState state) {\r
- // This match should prevent Last login: from being recognized by the above match\r
- state.addVar("gotLogin", Boolean.TRUE);\r
- state.exp_continue();\r
- }\r
- }),*/\r
- new GlobMatch("PassWord:", new Closure() {\r
- public void run(ExpectState state) {\r
- try { expect.send(password + "\r");} catch(Exception e) { /*Expect4j.log.warning*/logger.info(e.getMessage() ); }\r
- state.addVar("sentPassword", Boolean.TRUE);\r
- state.exp_continue();\r
- }\r
- }),\r
- new RegExpMatch(/*"@" + hostname + "\\]"*/"admin#", new Closure() {\r
- public void run(ExpectState state) {\r
- /*Expect4j.log.warning*/logger.info("Holy crap, this actually worked");\r
- state.addVar("sentExit", Boolean.TRUE);\r
- try { expect.send("exit\r"); } catch(Exception e) { }\r
- }\r
- }),\r
- /*\r
- new EofMatch(new Closure() {\r
- public void run(ExpectState state) {\r
- // suck up everything until EOF\r
- state.addVar("gotEOF", Boolean.TRUE);\r
- expect.log.warning("EOF");\r
- }\r
- }),\r
- */\r
- new TimeoutMatch(new Closure() {\r
- public void run(ExpectState state) {\r
- /*Expect4j.log.warning*/logger.info(":-( Timeout");\r
- }\r
- })\r
- });\r
- \r
- expect.close();\r
- \r
- ExpectState lastState = expect.getLastState();\r
- \r
- Boolean result = (Boolean) lastState.getVar("sentUsername");\r
- assertNotNull( result );\r
- \r
- result = (Boolean) lastState.getVar("sentPassword");\r
- assertNotNull( result );\r
- \r
- /*result = (Boolean) lastState.getVar("gotLogin");\r
- assertNotNull( result );*/\r
-\r
- result = (Boolean) lastState.getVar("sentExit");\r
- assertNotNull( result );\r
- \r
- //result = (Boolean) lastState.getVar("gotEOF");\r
- //assertNotNull( result );\r
- }\r
-\r
- public static void main(String args[]){\r
- new ExpectUtilsTelnetTest();\r
- }\r
-}\r