initial commit

This commit is contained in:
Jörg Prante 2017-11-16 00:37:06 +01:00
commit 832c86a73d
192 changed files with 27423 additions and 0 deletions

9
.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
/.idea
/.settings
/.classpath
/.project
/.gradle
build
.DS_Store
*.iml
*.properties

14
CREDITS.txt Normal file
View file

@ -0,0 +1,14 @@
This software is based on the work of
Zebulun https://github.com/jafer-org/zebulun
a low level Java implementation of the NISO Z39.50 protocol,
and
Java Access For Electronic Resources (Jafer) https://github.com/jafer-org/jafer
The JAFER Project (Java Access For Electronic Resources) was a Jisc funded project (2000 - 2003)
based at Oxford University to produce an easy to use toolkit for building portals
and information sources without having to deal with the technical intricacies of the Z39.50 protocol.

202
LICENSE.txt Normal file
View file

@ -0,0 +1,202 @@
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:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) 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
(d) 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.

View file

@ -0,0 +1,323 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- This is a checkstyle configuration file. For descriptions of
what the following rules do, please see the checkstyle configuration
page at http://checkstyle.sourceforge.net/config.html -->
<module name="Checker">
<module name="FileTabCharacter">
<!-- Checks that there are no tab characters in the file.
-->
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!-- Checks that FIXME is not used in comments. TODO is preferred.
-->
<property name="format" value="((//.*)|(\*.*))FIXME" />
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="RegexpSingleline">
<!-- Checks that TODOs are named. (Actually, just that they are followed
by an open paren.)
-->
<property name="format" value="((//.*)|(\*.*))TODO[^(]" />
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="JavadocPackage">
<!-- Checks that each Java package has a Javadoc file used for commenting.
Only allows a package-info.java, not package.html. -->
</module>
<!-- All Java AST specific tests live under TreeWalker module. -->
<module name="TreeWalker">
<!--
IMPORT CHECKS
-->
<module name="RedundantImport">
<!-- Checks for redundant import statements. -->
<property name="severity" value="error"/>
</module>
<module name="ImportOrder">
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<property name="groups" value="com.google,android,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
<property name="severity" value="error"/>
</module>
<module name="JavadocStyle">
<property name="severity" value="warning"/>
</module>
<!--
NAMING CHECKS
-->
<!-- Item 38 - Adhere to generally accepted naming conventions -->
<module name="PackageName">
<!-- Validates identifiers for package names against the
supplied expression. -->
<!-- Here the default checkstyle rule restricts package name parts to
seven characters, this is not in line with common practice at Google.
-->
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
<property name="severity" value="warning"/>
</module>
<module name="TypeNameCheck">
<!-- Validates static, final fields against the
expression "^[A-Z][a-zA-Z0-9]*$". -->
<metadata name="altname" value="TypeName"/>
<property name="severity" value="warning"/>
</module>
<module name="ConstantNameCheck">
<!-- Validates non-private, static, final fields against the supplied
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
<metadata name="altname" value="ConstantName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="false"/>
<property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
<message key="name.invalidPattern"
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
<property name="severity" value="warning"/>
</module>
<module name="StaticVariableNameCheck">
<!-- Validates static, non-final fields against the supplied
expression "^[a-z][a-zA-Z0-9]*_?$". -->
<metadata name="altname" value="StaticVariableName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
<property name="severity" value="warning"/>
</module>
<module name="MemberNameCheck">
<!-- Validates non-static members against the supplied expression. -->
<metadata name="altname" value="MemberName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<property name="severity" value="warning"/>
</module>
<module name="MethodNameCheck">
<!-- Validates identifiers for method names. -->
<metadata name="altname" value="MethodName"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
<property name="severity" value="warning"/>
</module>
<module name="ParameterName">
<!-- Validates identifiers for method parameters against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalFinalVariableName">
<!-- Validates identifiers for local final variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalVariableName">
<!-- Validates identifiers for local variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<!--
LENGTH and CODING CHECKS
-->
<module name="LineLength">
<!-- Checks if a line is too long. -->
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="128"/>
<property name="severity" value="error"/>
<!--
The default ignore pattern exempts the following elements:
- import statements
- long URLs inside comments
-->
<property name="ignorePattern"
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
default="^(package .*;\s*)|(import .*;\s*)|( *(\*|//).*https?://.*)$"/>
</module>
<module name="LeftCurly">
<!-- Checks for placement of the left curly brace ('{'). -->
<property name="severity" value="warning"/>
</module>
<module name="RightCurly">
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
the same line. e.g., the following example is fine:
<pre>
if {
...
} else
</pre>
-->
<!-- This next example is not fine:
<pre>
if {
...
}
else
</pre>
-->
<property name="option" value="same"/>
<property name="severity" value="warning"/>
</module>
<!-- Checks for braces around if and else blocks -->
<module name="NeedBraces">
<property name="severity" value="warning"/>
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
</module>
<module name="UpperEll">
<!-- Checks that long constants are defined with an upper ell.-->
<property name="severity" value="error"/>
</module>
<module name="FallThrough">
<!-- Warn about falling through to the next case statement. Similar to
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
some other variants which we don't publicized to promote consistency).
-->
<property name="reliefPattern"
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
<property name="severity" value="error"/>
</module>
<!--
MODIFIERS CHECKS
-->
<module name="ModifierOrder">
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
8.4.3. The prescribed order is:
public, protected, private, abstract, static, final, transient, volatile,
synchronized, native, strictfp
-->
</module>
<!--
WHITESPACE CHECKS
-->
<module name="WhitespaceAround">
<!-- Checks that various tokens are surrounded by whitespace.
This includes most binary operators and keywords followed
by regular or curly braces.
-->
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
<property name="severity" value="error"/>
</module>
<module name="WhitespaceAfter">
<!-- Checks that commas, semicolons and typecasts are followed by
whitespace.
-->
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
</module>
<module name="NoWhitespaceAfter">
<!-- Checks that there is no whitespace after various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
UNARY_PLUS"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="NoWhitespaceBefore">
<!-- Checks that there is no whitespace before various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="ParenPad">
<!-- Checks that there is no whitespace before close parens or after
open parens.
-->
<property name="severity" value="warning"/>
</module>
</module>
</module>

View file

@ -0,0 +1,24 @@
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<localRepository>~/.m2/repository</localRepository>
<activeProfiles>
<activeProfile>xbib</activeProfile>
</activeProfiles>
<profiles>
<profile>
<id>xbib</id>
<repositories>
<repository>
<id>xbib</id>
<url>http://xbib.org/repository</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>

View file

@ -0,0 +1,94 @@
package org.xbib.asn1;
/**
* ASN1 ANY
* The ANY type denotes an arbitary value of an arbitary type.
* This class also serves as the base class for all ASN.1 classes.
* The ASN.1 syntax is defined in
* <strong>Information Technology - Open Systems Interconnection -
* Specification of Abstract Syntax Notation One (ASN.1)</strong>
* AS 3625-1991
* ISO/IEC 8824:1990
* The current implementation assumes values are limited to 32-bit
* signed integers for tags, lengths, etc.
*/
public class ASN1Any {
/* Hack to support creation of ASN1 ANY types from a BER and have
it behave normally. This is not used by any other ASN.1 subclasses.
It is a waste of space in that respect. */
private BEREncoding asn1anyBer;
public ASN1Any() {
//
}
/**
* Constructor for an ASN.1 ANY object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Does nothing for ASN1Any.
* @throws ASN1Exception if the BER encoding is incorrect.
*/
public ASN1Any(BEREncoding ber, boolean checkTag) throws ASN1Exception {
berDecode(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
* All classes derived from this one must implement a version of this.
* This method will be overridden by derived types.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Does nothing for ASN1Any.
* @throws ASN1Exception If the BER encoding is incorrect.
* Never occurs for ASN1Any.
*/
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1Exception {
asn1anyBer = berEncoding;
}
/**
* Constructs a BER encoding for this ASN.1 object.
* This method is usually overridden by a subclass method.
*
* @return BER encoding
* @throws ASN1Exception If the object cannot be BER encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
if (asn1anyBer == null) {
throw new ASN1EncodingException("uninitialised");
}
return asn1anyBer;
}
/**
* Returns a BER encoding of ASN1Any, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag number.
* @return The BER encoding of the object.
* @throws ASN1Exception when invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
if (asn1anyBer == null) {
throw new ASN1EncodingException("uninitialised");
}
throw new ASN1EncodingException("cannot implicitly tag");
}
/**
* Returns a new String object representing this ASN.1 object's value.
*
* @return A text string representation.
*/
@Override
public String toString() {
if (asn1anyBer == null) {
return "<empty ASN.1 ANY>";
}
return asn1anyBer.toString();
}
}

View file

@ -0,0 +1,156 @@
package org.xbib.asn1;
/**
* Representation of an ASN.1 <code>BIT STRING</code>.
* The BIT STRING type denotes an arbitary string of bits (ones and zeros).
* A BIT STRING value can have any length, including zero. The type is a
* string type.
*/
public final class ASN1BitString extends ASN1Any {
/**
* This constant is the ASN.1 UNIVERSAL tag value for BIT STRING.
*/
public static final int BIT_STRING_TAG = 0x03;
/**
* The values of the BIT STRING are stored in this array of boolean
* values.
*/
private boolean[] bits;
/**
* Constructor for an ASN.1 BIT STRING object. It sets the tag
* to the default value of UNIVERSAL 3, and the bits to the
* given bit values.
*
* @param bitValues - array of booleans representing the bit string.
*/
public ASN1BitString(boolean[] bitValues) {
bits = bitValues;
}
/**
* Constructor for an ASN.1 BIT STRING object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1BitString(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag); // superclass will call berDecode
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1EncodingException If the BER encoding is incorrect.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1EncodingException {
if (checkTag && (berEncoding.tagGet() != BIT_STRING_TAG || berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("ASN.1 BIT STRING: bad BER: tag=" + berEncoding.tagGet() +
" expected " + BIT_STRING_TAG + "\n");
}
if (berEncoding instanceof BERPrimitive) {
BERPrimitive ber = (BERPrimitive) berEncoding;
int[] encoding = ber.peek();
if (encoding.length < 1) {
throw new ASN1EncodingException("ASN1 BIT STRING: invalid encoding, length = " + encoding.length);
}
int unusedBits = encoding[0] & 0x07;
int numBits = (encoding.length - 1) * 8 - unusedBits;
bits = new boolean[numBits];
for (int bit = 0; bit < numBits; bit++) {
int octet = encoding[bit / 8 + 1];
octet <<= (bit % 8);
bits[bit] = (octet & 0x80) != 0;
}
} else {
throw new ASN1EncodingException("ASN.1 BIT STRING: decoding constructed NOT IMPLEMENTED YET");
}
}
/**
* Returns a BER encoding of the BIT STRING.
* Bit strings can have a primitive encoding and a constructed
* encoding. This method performs the primitive encoding (which
* is the one specified for DER encoding).
*
* @return The BER encoding of the BIT STRING
* @throws ASN1Exception when the BIT STRING is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, BIT_STRING_TAG);
}
/**
* Returns a BER encoding of the BIT STRING.
* Bit strings can have a primitive encoding and a constructed
* encoding. This method performs the primitive encoding (which
* is the one specified for DER encoding).
*
* @return The BER encoding of the BIT STRING
* @throws ASN1Exception when the BIT STRING is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numOctets = (bits.length + 7) / 8;
int[] encoding = new int[numOctets + 1];
encoding[0] = (numOctets * 8) - bits.length;
for (int count = 1; count <= numOctets; count++) {
encoding[count] = 0x00;
int bitBaseIndex = (count - 1) * 8;
for (int bitIndex = 0; bitIndex < 8; bitIndex++) {
int n = bitBaseIndex + bitIndex;
encoding[count] <<= 1;
if (n < bits.length && bits[n]) {
encoding[count] |= 0x01;
}
}
}
return new BERPrimitive(tagType, tag, encoding);
}
/**
* Method to set the bit string's value.
*
* @param newBits the value to set the BIT STRING to.
* @return the object.
*/
public ASN1BitString set(boolean[] newBits) {
bits = newBits;
return this;
}
/**
* Method to get the bit string's value.
*
* @return the BIT STRING's current value.
*/
public boolean[] get() {
return bits;
}
/**
* Returns a new String object representing this ASN.1 object's value.
*
* @return A text string representation of the BitString.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append('\'');
for (boolean bit : bits) {
str.append(bit ? '1' : '0');
}
str.append("'B");
return str.toString();
}
}

View file

@ -0,0 +1,127 @@
package org.xbib.asn1;
/**
* Representation of an ASN.1 <code>BOOLEAN</code>.
* The BOOLEAN type denotes a Boolean value: either true or false.
*/
public final class ASN1Boolean extends ASN1Any {
/**
* This constant is the ASN.1 UNIVERSAL tag value for BOOLEAN.
*/
public static final int TAG = 0x01;
/**
* The value of the BOOLEAN is stored in this variable.
*/
private boolean value;
/**
* Default constructor for an ASN.1 BOOLEAN object. It sets the tag
* to the default of UNIVERSAL 1, and the value to bool.
*
* @param bool the value of the BOOLEAN.
*/
public ASN1Boolean(boolean bool) {
value = bool;
}
/**
* Constructor for an ASN.1 BOOLEAN object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception if the BER encoding is incorrect.
*/
public ASN1Boolean(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag); // superclass will call berDecode
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1EncodingException if the BER encoding is incorrect.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1EncodingException {
if (checkTag && (berEncoding.tagGet() != TAG || berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException
("ASN.1 BOOLEAN: bad BER: tag=" + berEncoding.tagGet() +
" expected " + "TAG\n");
}
if (berEncoding instanceof BERPrimitive) {
BERPrimitive ber = (BERPrimitive) berEncoding;
int[] encoding = ber.peek();
if (encoding.length != 1) {
throw new ASN1EncodingException("ASN.1 BOOLEAN: invalid encoding, length = " + encoding.length);
}
value = encoding[0] != 0;
} else {
throw new ASN1EncodingException
("ASN.1 BOOLEAN: bad BER: decoding constructed NOT IMPLEMENTED YET");
}
}
/**
* Returns a BER encoding of the BOOLEAN.
*
* @return The BER encoding of the BOOLEAN
* @throws ASN1Exception when the BOOLEAN is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode()
throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, TAG);
}
/**
* Returns a BER encoding of the BOOLEAN. Implicitly tagged.
*
* @return The BER encoding of the BOOLEAN
* @throws ASN1Exception when the BOOLEAN is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int[] encoding = new int[1];
if (value) {
encoding[0] = 0xff; // TRUE (in fact, any non-zero will do)
} else {
encoding[0] = 0x00; // FALSE
}
return new BERPrimitive(tagType, tag, encoding);
}
/**
* Method to set the boolean's value.
*
* @param newVal the value to set the BOOLEAN to.
* @return the boolean
*/
public ASN1Boolean set(boolean newVal) {
value = newVal;
return this;
}
/**
* Method to get the boolean's value.
*
* @return the BOOLEAN's current value.
*/
public boolean get() {
return value;
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
return value ? "true" : "false";
}
}

View file

@ -0,0 +1,66 @@
package org.xbib.asn1;
/**
* ASN1Decoder.
* This is an ASN1 decoder which can handle all the standard ASN.1 types
* (those with UNIVERSAL tag types).
* It is used for decoding generic BER encodings into ASN.1 objects.
*/
public class ASN1Decoder {
private ASN1Decoder() {
// private constructor
}
public static ASN1Any toASN1(BEREncoding ber) throws ASN1Exception {
if (ber.tagTypeGet() == BEREncoding.UNIVERSAL_TAG) {
switch (ber.tagGet()) {
case ASN1Boolean.TAG:
return new ASN1Boolean(ber, true);
case ASN1Integer.INTEGER_TAG:
return new ASN1Integer(ber, true);
case ASN1BitString.BIT_STRING_TAG:
return new ASN1BitString(ber, true);
case ASN1OctetString.OCTET_STRING_TAG:
return new ASN1OctetString(ber, true);
case ASN1Null.NULL_TAG:
return new ASN1Null(ber, true);
case ASN1ObjectIdentifier.OBJECT_IDENTIFIER_TAG:
return new ASN1ObjectIdentifier(ber, true);
case ASN1ObjectDescriptor.OBJECT_DESCRIPTOR_TAG:
return new ASN1ObjectDescriptor(ber, true);
case ASN1External.EXTERNAL_TAG:
return new ASN1External(ber, true);
case ASN1Enumerated.ENUMERATED_TAG:
return new ASN1Enumerated(ber, true);
case ASN1Sequence.SEQUENCE_TAG:
return new ASN1Sequence(ber, true);
case ASN1Set.SET_TAG:
return new ASN1Set(ber, true);
case ASN1NumericString.NUMERIC_STRING_TAG:
return new ASN1NumericString(ber, true);
case ASN1PrintableString.PRINTABLE_STRING_TAG:
return new ASN1PrintableString(ber, true);
case ASN1T61String.T61_STRING_TAG:
return new ASN1T61String(ber, true);
case ASN1VideotexString.VIDEOTEX_STRING_TAG:
return new ASN1VideotexString(ber, true);
case ASN1IA5String.IA5_STRING_TAG:
return new ASN1IA5String(ber, true);
case ASN1UTCTime.UTC_TIME_TAG:
return new ASN1UTCTime(ber, true);
case ASN1GeneralizedTime.GENERALIZED_TIME_TAG:
return new ASN1GeneralizedTime(ber, true);
case ASN1GraphicString.GRAPHIC_STRING_TAG:
return new ASN1GraphicString(ber, true);
case ASN1VisibleString.TAG:
return new ASN1VisibleString(ber, true);
case ASN1GeneralString.GENERAL_STRING_TAG:
return new ASN1GeneralString(ber, true);
default:
break;
}
}
return new ASN1Any(ber, true);
}
}

View file

@ -0,0 +1,16 @@
package org.xbib.asn1;
/**
* ASN1EncodingException.
*/
public class ASN1EncodingException extends ASN1Exception {
private static final long serialVersionUID = 2063392457642967553L;
public ASN1EncodingException() {
super("ASN.1 encoding exception");
}
public ASN1EncodingException(String message) {
super(message);
}
}

View file

@ -0,0 +1,147 @@
package org.xbib.asn1;
/**
* Representation of an ASN.1 ENUMERATED.
* The <code>ENUMERATED</code> type denotes an integer from a selected set.
* ASN.1 ENUMERATED values can be positive, negative, or zero; and can
* have any magnitude.
* The current implementation limits the values of ENUMERATED to 32-bit
* two's complement values.
*/
public final class ASN1Enumerated extends ASN1Any {
/**
* This constant is the ASN.1 UNIVERSAL tag value for ENUMERATED.
*/
public static final int ENUMERATED_TAG = 0x0A;
/**
* The value of the ENUMERATED is stored in this variable.
* This is private for good information hiding, so that we are able
* to change its representation (e.g. to a long) at a later date
* without affecting the interface.
*/
private int value;
/**
* Constructor for an ASN.1 ENUMERATED object. The tag is
* set to the default tag of UNIVERSAL 2, and the value to the
* given number.
*
* @param number the value of the ENUMERATED.
*/
public ASN1Enumerated(int number) {
value = number;
}
/**
* Constructor for an ASN.1 ENUMERATED object from a BER encoding.
* @param ber the BER encoding
* @param checkTag the check tag
* @throws ASN1Exception if the BER encoding is incorrect.
*/
public ASN1Enumerated(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
*
* @throws ASN1EncodingException if the BER encoding is incorrect.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1EncodingException {
if (checkTag && (berEncoding.tagGet() != ENUMERATED_TAG ||
berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + berEncoding.tagGet() +
" expected " + ENUMERATED_TAG + "\n");
}
if (!(berEncoding instanceof BERPrimitive)) {
throw new ASN1EncodingException("bad form, constructed");
}
BERPrimitive ber = (BERPrimitive) berEncoding;
int[] encoding = ber.peek();
if (encoding.length < 1) {
throw new ASN1EncodingException("invalid encoding, length = " + encoding.length);
}
value = (byte) encoding[0]; // to ensure sign extension
for (int x = 1; x < encoding.length; x++) {
value <<= 8;
value |= (encoding[x] & 0xff);
}
}
/**
* Returns a BER encoding of the ENUMERATED.
*
* @return The BER encoding of the ENUMERATED
* @throws ASN1Exception when the ENUMERATED is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ENUMERATED_TAG);
}
/**
* Returns a BER encoding of the ENUMERATED. Explicitly tagged with
* the supplied tag.
*
* @return The BER encoding of the ENUMERATED
* @throws ASN1Exception when the ENUMERATED is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int length = 0;
int shifted = value;
if (value < 0) {
shifted = ~value;
}
boolean needPad;
do {
needPad = (shifted & 0x80) == 0x80;
shifted >>= 8;
length++;
} while (shifted != 0);
if (needPad) {
length++;
}
int[] encoding = new int[length];
int index = 0;
while (0 < length) {
encoding[index++] = (value >> (8 * (length - 1))) & 0xff;
length--;
}
return new BERPrimitive(tagType, tag, encoding);
}
/**
* Method to set the integer's value.
*
* @param newVal the value to set the ENUMERATED to.
* @return the object.
*/
public ASN1Enumerated set(int newVal) {
value = newVal;
return this;
}
/**
* Method to get the integer's value.
*
* @return the ENUMERATED's current value.
*/
public int get() {
return value;
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
return String.valueOf(value);
}
}

View file

@ -0,0 +1,18 @@
package org.xbib.asn1;
import java.io.IOException;
/**
* ASN1Exception.
*/
public class ASN1Exception extends IOException {
private static final long serialVersionUID = -339688617660261367L;
public ASN1Exception() {
super("ASN.1 exception");
}
public ASN1Exception(String message) {
super(message);
}
}

View file

@ -0,0 +1,282 @@
package org.xbib.asn1;
/**
* ASN1 EXTERNAL
* The <code>EXTERNAL</code> type represents an external object.
* According to clause 34.4 of the ASN.1 standard,
* the EXTERNAL type can be defined as:
* <pre>
* EXTERNAL := [UNIVERSAL 8] IMPLICIT SEQUENCE {
* direct_reference OBJECT IDENTIFIER OPTIONAL,
* indirect_reference INTEGER OPTIONAL,
* data_value_descriptor ObjectDescriptor OPTIONAL,
* encoding CHOICE {
* single_ASN1_type [0] ANY,
* octet_Aligned [1] IMPLICIT OCTET STRING,
* arbitrary [2] IMPLICIT BIT STRING
* }
* }
* </pre>
* This construct has been represented by a class with six
* variables:
* sDirectReference,
* sIndirectReference,
* sDataValueDescriptor,
* cSingleASN1Type,
* cOctetAligned,
* cArbitrary.
* The first three should be set to point to the appropriate object
* if present, or null if not.
* One of the last three variables should be set to non-null (the choice)
* and the rest to null.
*/
public final class ASN1External extends ASN1Any {
/**
* This constant is the ASN.1 UNIVERSAL tag value for an EXTERNAL.
*/
public static final int EXTERNAL_TAG = 0x08;
/*
* The values are stored in these variables.
*/
private ASN1ObjectIdentifier sDirectReference;
private ASN1Integer sIndirectReference;
private ASN1ObjectDescriptor sDataValueDescriptor;
private ASN1Any cSingleASN1Type;
private ASN1OctetString cOctetAligned;
private ASN1BitString cArbitrary;
/**
* Constructor for an ASN.1 EXTERNAL object. It sets the tag to the
* default value of UNIVERSAL 8.
*/
public ASN1External() {
//
}
/**
* Constructor for an ASN.1 EXTERNAL object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1External(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1Exception {
if (checkTag && (berEncoding.tagGet() != EXTERNAL_TAG || berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + berEncoding.tagGet() +
" expected " + EXTERNAL_TAG + "\n");
}
if (berEncoding instanceof BERPrimitive) {
throw new ASN1EncodingException("incorrect form, primitive encoding");
}
BERConstructed ber = (BERConstructed) berEncoding;
sDirectReference = null;
sIndirectReference = null;
sDataValueDescriptor = null;
cSingleASN1Type = null;
cOctetAligned = null;
cArbitrary = null;
int numParts = ber.numberComponents();
if (numParts < 1) {
throw new ASN1EncodingException("incomplete");
}
int part = 0;
BEREncoding p = ber.elementAt(part);
if (p.tagGet() == ASN1ObjectIdentifier.OBJECT_IDENTIFIER_TAG &&
p.tagTypeGet() == BEREncoding.UNIVERSAL_TAG) {
sDirectReference = new ASN1ObjectIdentifier(p, true);
if (numParts <= ++part) {
throw new ASN1EncodingException("incomplete");
}
p = ber.elementAt(part);
}
if (p.tagGet() == ASN1Integer.INTEGER_TAG &&
p.tagTypeGet() == BEREncoding.UNIVERSAL_TAG) {
sIndirectReference = new ASN1Integer(p, true);
if (numParts <= ++part) {
throw new ASN1EncodingException("incomplete");
}
p = ber.elementAt(part);
}
if (p.tagGet() == ASN1ObjectDescriptor.OBJECT_DESCRIPTOR_TAG &&
p.tagTypeGet() == BEREncoding.UNIVERSAL_TAG) {
sDataValueDescriptor = new ASN1ObjectDescriptor(p, true);
if (numParts <= ++part) {
throw new ASN1EncodingException("incomplete");
}
p = ber.elementAt(part);
}
switch (p.tagGet()) {
case 0:
if (!(p instanceof BERConstructed)) {
throw new ASN1EncodingException("singleASN1type: bad form, primitive");
}
if (((BERConstructed) p).numberComponents() != 1) {
throw new ASN1EncodingException("singleASN1type: bad form, no explicit tag");
}
cSingleASN1Type = ASN1Decoder.toASN1(((BERConstructed) p).elementAt(0));
break;
case 1:
// octetAligned [1] IMPLICIT OCTET STRING
if (p.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("encoding: bad tag type " + p);
}
cOctetAligned = new ASN1OctetString(p, false);
break;
case 2:
// arbitrary [2] IMPLICIT BIT STRING
if (p.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("encoding: bad tag type " + p);
}
cArbitrary = new ASN1BitString(p, false);
break;
default:
throw new ASN1EncodingException("encoding: tag = " + p.tagGet());
}
if (part != (numParts - 1)) {
throw new ASN1Exception("extra element(s)");
}
}
public ASN1OctetString getcOctetAligned() {
return cOctetAligned;
}
public ASN1Any getSingleASN1Type() {
return cSingleASN1Type;
}
/**
* Returns a BER encoding of the EXTERNAL.
*
* @return The BER encoding of the EXTERNAL
* @throws ASN1Exception when the EXTERNAL is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, EXTERNAL_TAG);
}
/**
* Returns a BER encoding of the EXTERNAL.
*
* @return The BER encoding of the EXTERNAL
* @throws ASN1Exception when the EXTERNAL is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numParts = 0;
if (cSingleASN1Type != null) {
numParts++;
}
if (cOctetAligned != null) {
numParts++;
}
if (cArbitrary != null) {
numParts++;
}
if (numParts < 1) {
throw new ASN1Exception("no encoding has been set");
}
if (1 < numParts) {
throw new ASN1Exception("more than one encoding set");
}
if (sDirectReference != null) {
numParts++;
}
if (sIndirectReference != null) {
numParts++;
}
if (sDataValueDescriptor != null) {
numParts++;
}
BEREncoding[] parts = new BEREncoding[numParts];
int part = 0;
if (sDirectReference != null) {
parts[part++] = sDirectReference.berEncode();
}
if (sIndirectReference != null) {
parts[part++] = sIndirectReference.berEncode();
}
if (sDataValueDescriptor != null) {
parts[part++] = sDataValueDescriptor.berEncode();
}
if (cSingleASN1Type != null) {
BEREncoding[] contents = new BEREncoding[1];
contents[0] = cSingleASN1Type.berEncode();
parts[part] = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 0,
contents);
} else if (cOctetAligned != null) {
parts[part] = cOctetAligned.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG,
1);
} else if (cArbitrary != null) {
parts[part] = cArbitrary.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG,
2);
}
return new BERConstructed(tagType, tag, parts);
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder("{");
boolean hasElement = false;
if (sDirectReference != null) {
str.append("directReference ");
str.append(sDirectReference);
hasElement = true;
}
if (sIndirectReference != null) {
if (hasElement) {
str.append(", ");
}
str.append("indirectReference ");
str.append(sIndirectReference);
hasElement = true;
}
if (sDataValueDescriptor != null) {
if (hasElement) {
str.append(", ");
}
str.append("dataValueDescriptor ");
str.append(sDataValueDescriptor);
hasElement = true;
}
if (hasElement) {
str.append(", ");
}
str.append("encoding {");
if (cSingleASN1Type != null) {
str.append("singleASN1type ");
str.append(cSingleASN1Type);
}
if (cOctetAligned != null) {
str.append("octetAligned ");
str.append(cOctetAligned);
}
if (cArbitrary != null) {
str.append("arbitrary ");
str.append(cArbitrary);
}
str.append("}}");
return str.toString();
}
}

View file

@ -0,0 +1,49 @@
package org.xbib.asn1;
/**
* ASN.1 GeneralString.
* The <code>GeneralString</code> type denotes an arbitary string
* of General characters.
* This type is a string type.
*/
public class ASN1GeneralString extends ASN1OctetString {
/**
* This constant is the UNIVERSAL tag value for GeneralString.
*/
public static final int GENERAL_STRING_TAG = 0x1B;
/**
* Constructor for a GeneralString object. It sets the tag to the
* default value of UNIVERSAL 27 (0x1B).
*
* @param value The string value.
*/
public ASN1GeneralString(String value) {
super(value);
}
/**
* Constructor for a GeneralString object from a primitive BER encoding.
* @param ber ber
* @param checkTag check tag
* @throws ASN1Exception if the BER encoding is incorrect.
*/
public ASN1GeneralString(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != GENERAL_STRING_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + ber.tagGet() +
" expected " + GENERAL_STRING_TAG + "\n");
}
}
/**
* Encode with no explicit tag.
*
* @throws ASN1Exception if the BER encoding cannot be made.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, GENERAL_STRING_TAG);
}
}

View file

@ -0,0 +1,51 @@
package org.xbib.asn1;
/**
* ASN.1 GeneralizedTime.
* The <code>GeneralizedTime</code> type denotes a string corrsponding
* to an ISO 8601 date string.
* This type is a string type.
*/
public final class ASN1GeneralizedTime extends ASN1VisibleString {
/**
* This constant is the UNIVERSAL tag value for GeneralizedTime.
*/
public static final int GENERALIZED_TIME_TAG = 0x18;
/**
* Constructor for an GeneralizedTime object. It sets the tag to the
* default value of UNIVERSAL 24 (0x18).
* @param value value
*/
public ASN1GeneralizedTime(String value) {
super(value);
}
/**
* Constructor for a GeneralizedTime object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception if the BER encoding is incorrect.
*/
public ASN1GeneralizedTime(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != GENERALIZED_TIME_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + ber.tagGet() +
" expected " + GENERALIZED_TIME_TAG + "\n");
}
}
/**
* Returns a BER encoding with no implicit tag.
*
* @return The BER encoding
* @throws ASN1Exception when the object is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, GENERALIZED_TIME_TAG);
}
}

View file

@ -0,0 +1,40 @@
package org.xbib.asn1;
/**
* ASN.1 GraphicString.
* The <code>GraphicString</code> type denotes an arbitary string
* of Graphic characters.
* This type is a string type.
*/
public class ASN1GraphicString extends ASN1OctetString {
/**
* This constant is the UNIVERSAL tag value for GraphicString.
*/
public static final int GRAPHIC_STRING_TAG = 0x19;
/**
* Constructor for a GraphicString object. It sets the tag to the
* default value of UNIVERSAL 25 (0x19).
*
* @param value The string value
*/
public ASN1GraphicString(String value) {
super(value);
}
/**
* Constructor for a GraphicString object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception if the BER encoding is incorrect.
*/
public ASN1GraphicString(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != GRAPHIC_STRING_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + ber.tagGet() +
" expected " + GRAPHIC_STRING_TAG + "\n");
}
}
}

View file

@ -0,0 +1,51 @@
package org.xbib.asn1;
/**
* Representation for ASN.1 IA5String.
* The <code>IA5String</code> type denotes an arbitary string of IA5
* characters. IA5 stands for International Alphabet 5, which is
* the same as ASCII. The character set includes non-printing control
* characters. An IA5String can be of any length, including zero.
*/
public final class ASN1IA5String extends ASN1OctetString {
/**
* This constant is the ASN.1 UNIVERSAL tag value for IA5String.
*/
public static final int IA5_STRING_TAG = 0x16;
/**
* Constructor for a IA5String object. It sets the tag to the
* default value of UNIVERSAL 22 (0x16).
* @param value value
*/
public ASN1IA5String(String value) {
super(value);
}
/**
* Constructor for a IA5String object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1IA5String(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != IA5_STRING_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + ber.tagGet() +
" expected " + IA5_STRING_TAG + "\n");
}
}
/**
* Returns a BER encoding with no implicit tag.
*
* @return The BER encoding
* @throws ASN1Exception when the object is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, IA5_STRING_TAG);
}
}

View file

@ -0,0 +1,150 @@
package org.xbib.asn1;
/**
* Representation of an ASN.1 INTEGER.
* The <code>INTEGER</code> type denotes an arbitary integer.
* ASN.1 INTEGER values can be positive, negative, or zero; and can
* have any magnitude.
* The current implementation limits the values of INTEGERs to 32-bit
* two's complement values.
*/
public final class ASN1Integer extends ASN1Any {
/**
* This constant is the ASN.1 UNIVERSAL tag value for INTEGER.
*/
public static final int INTEGER_TAG = 0x02;
/**
* The value of the INTEGER is stored in this variable.
* This is private for good information hiding, so that we are able
* to change its representation (e.g. to a long) at a later date
* without affecting the interface.
*/
private int value;
/**
* Constructor for an ASN.1 INTEGER object. The tag is
* set to the default tag of UNIVERSAL 2, and the value to the
* given number.
*
* @param number the value of the INTEGER.
*/
public ASN1Integer(int number) {
value = number;
}
/**
* Constructor for an ASN.1 INTEGER object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1Integer(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1EncodingException If the BER encoding is incorrect.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1EncodingException {
if (checkTag && (berEncoding.tagGet() != INTEGER_TAG ||
berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + berEncoding.tagGet() +
" expected " + INTEGER_TAG + "\n");
}
if (!(berEncoding instanceof BERPrimitive)) {
throw new ASN1EncodingException("bad form, constructed");
}
BERPrimitive ber = (BERPrimitive) berEncoding;
int[] encoding = ber.peek();
if (encoding.length < 1) {
throw new ASN1EncodingException("invalid encoding, length = " + encoding.length);
}
value = (byte) encoding[0];
for (int x = 1; x < encoding.length; x++) {
value <<= 8;
value |= (encoding[x] & 0xff);
}
}
/**
* Returns a BER encoding of the INTEGER.
*
* @return The BER encoding of the INTEGER
* @throws ASN1Exception when the INTEGER is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, INTEGER_TAG);
}
/**
* Returns a BER encoding of the INTEGER. Explicitly tagged with
* the supplied tag.
*
* @return The BER encoding of the INTEGER
* @throws ASN1Exception when the INTEGER is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int length = 0;
int shifted = value;
if (value < 0) {
shifted = ~value;
}
boolean needPad;
do {
needPad = (shifted & 0x80) == 0x80;
shifted >>= 8;
length++;
} while (shifted != 0);
if (needPad) {
length++;
}
int[] encoding = new int[length];
int index = 0;
while (0 < length) {
encoding[index++] = (value >> (8 * (length - 1))) & 0xff;
length--;
}
return new BERPrimitive(tagType, tag, encoding);
}
/**
* Method to set the integer's value.
*
* @param newVal the value to set the INTEGER to.
* @return the object.
*/
public ASN1Integer set(int newVal) {
value = newVal;
return this;
}
/**
* Method to get the integer's value.
*
* @return the INTEGER's current value.
*/
public int get() {
return value;
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
return String.valueOf(value);
}
}

View file

@ -0,0 +1,85 @@
package org.xbib.asn1;
/**
* Representation of an ASN.1 NULL.
* This class represents a null value. A NULL is used
* when only the tag is of interest, and not any value.
*/
public final class ASN1Null extends ASN1Any {
/**
* This constant is the ASN.1 UNIVERSAL tag value for NULL.
*/
public static final int NULL_TAG = 0x05;
/**
* Default constructor for an ASN.1 NULL object. The tag is set
* to the default tag of UNIVERSAL 5. A NULL has no value.
*/
public ASN1Null() {
//
}
/**
* Constructor for an ASN.1 NULL object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1Null(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1EncodingException If the BER encoding is incorrect.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1EncodingException {
if (checkTag && (berEncoding.tagGet() != NULL_TAG ||
berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + berEncoding.tagGet() +
" expected " + NULL_TAG + "\n");
}
if (!(berEncoding instanceof BERPrimitive)) {
throw new ASN1EncodingException("bad form, constructed");
}
}
/**
* Returns a BER encoding of the NULL.
*
* @return The BER encoding of the NULL
* @throws ASN1Exception when the NULL is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, NULL_TAG);
}
/**
* Returns a BER encoding of the NULL.
*
* @return The BER encoding of the NULL
* @throws ASN1Exception when the NULL is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int[] encoding = new int[0];
return new BERPrimitive(tagType, tag, encoding);
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
return "null";
}
}

View file

@ -0,0 +1,49 @@
package org.xbib.asn1;
/**
* Representation for an ASN.1 NumericString.
* The <code>NumericString</code> type denotes an arbitary string
* of Numeric characters (digits and space).
* This type is a string type.
*/
public class ASN1NumericString extends ASN1OctetString {
/**
* This constant is the ASN.1 UNIVERSAL tag value for NumericString.
*/
public static final int NUMERIC_STRING_TAG = 0x12;
/**
* Constructor for an ASN.1 NumericString object. It sets the tag to the
* default value of UNIVERSAL 18 (0x12).
* @param value value
*/
public ASN1NumericString(String value) {
super(value);
}
/**
* Constructor for a NumericString object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1NumericString(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != NUMERIC_STRING_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + ber.tagGet() +
" expected " + NUMERIC_STRING_TAG + "\n");
}
}
/**
* Encodes the numeric string.
*
* @throws ASN1Exception if the BER encoding cannot be formed.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, NUMERIC_STRING_TAG);
}
}

View file

@ -0,0 +1,53 @@
package org.xbib.asn1;
/**
* Representation for an ASN.1 OBJECT DESCRIPTOR.
* The ASN.1 OBJECT DESCRIPTOR consists of a human-readable text
* which serves to describe an information object.
* According to clause 35.3 of the standard,
* ObjectDescriptor ::= [UNIVERSAL 7] IMPLICIT GraphicString
*/
public final class ASN1ObjectDescriptor extends ASN1GraphicString {
/**
* This constant is the UNIVERSAL tag value for ObjectDescriptor.
*/
public static final int OBJECT_DESCRIPTOR_TAG = 0x07;
/**
* Constructor for an ObjectDescriptor object. It sets the tag to the
* default value of UNIVERSAL 7, and the descriptor to the given value.
* @param descriptor descriptor
*/
public ASN1ObjectDescriptor(String descriptor) {
super(descriptor);
}
/**
* Constructor for a ObjectDescriptor object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception if the BER encoding is incorrect.
*/
public ASN1ObjectDescriptor(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != OBJECT_DESCRIPTOR_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException
("ASN.1 ObjectDescriptor: bad BER: tag=" + ber.tagGet() +
" expected " + OBJECT_DESCRIPTOR_TAG + "\n");
}
}
/**
* Returns a BER encoding with no implicit tag.
*
* @return The BER encoding
* @throws ASN1Exception when the object is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, OBJECT_DESCRIPTOR_TAG);
}
}

View file

@ -0,0 +1,193 @@
package org.xbib.asn1;
/**
* Representation of an ASN.1 OBJECT IDENTIFIER.
* The <code>OBJECT IDENTIFIER</code> type denotes an object identifier,
* which is a sequence of integer components. An OBJECT IDENTIFIER can
* have any number of components, whch are generally non-negative.
* This type is a non-string type.
*/
public final class ASN1ObjectIdentifier extends ASN1Any {
/**
* This constant is the ASN.1 UNIVERSAL tag value for OBJECT IDENTIFIER.
*/
public static final int OBJECT_IDENTIFIER_TAG = 0x06;
/**
* The components of the OBJECT IDENTIFER are stored in this
* variable as an array of integers.
*/
private int[] oid;
/**
* Constructor for an ASN.1 OBJECT IDENTIFER object. The tag is set
* to the default tag of UNIVERSAL 6, and the given OID value.
* @param oidValue OID
*/
public ASN1ObjectIdentifier(int[] oidValue) {
oid = oidValue;
}
/**
* Constructor for an ASN.1 OBJECT IDENTIFIER object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1ObjectIdentifier(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1EncodingException If the BER encoding cannot be decoded.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag) throws ASN1EncodingException {
if (checkTag && (berEncoding.tagGet() != OBJECT_IDENTIFIER_TAG ||
berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + berEncoding.tagGet() +
" expected " + OBJECT_IDENTIFIER_TAG + "\n");
}
if (!(berEncoding instanceof BERPrimitive)) {
throw new ASN1EncodingException("bad form, constructed");
}
BERPrimitive ber = (BERPrimitive) berEncoding;
int[] encoding = ber.peek();
if (encoding.length < 2) {
throw new ASN1EncodingException("invalid encoding, length = " +
encoding.length);
}
int numComponents = 2;
for (int index = 1; index < encoding.length; index++) {
if ((encoding[index] & 0x80) == 0) {
numComponents++;
}
}
oid = new int[numComponents];
oid[0] = encoding[0] / 40;
oid[1] = encoding[0] % 40;
int index = 1;
for (int component = 2; component < numComponents; component++) {
oid[component] = 0;
int octet;
do {
octet = encoding[index++];
oid[component] <<= 7;
oid[component] |= (octet & 0x7f);
} while ((octet & 0x80) != 0);
}
}
/**
* Returns a BER encoding of the OBJECT IDENTIFIER.
* The current implementation rejects negative OID components (should it?)
*
* @return The BER encoding of the OBJECT IDENTIFIER
* @throws ASN1Exception when the OBJECT IDENTIFIER is invalid
* and cannot be encoded. According to X.208, an OBJECT
* IDENTIFIER must have at least two components, the first
* has values of (0, 1, or 2) and the second between 0 and 39
* inclusive.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, OBJECT_IDENTIFIER_TAG);
}
/**
* Returns a BER encoding of the OBJECT IDENTIFIER.
* The current implementation rejects negative OID components.
*
* @return The BER encoding of the OBJECT IDENTIFIER
* @throws ASN1Exception when the OBJECT IDENTIFIER is invalid
* and cannot be encoded. According to X.208, an OBJECT
* IDENTIFIER must have at least two components, the first
* has values of (0, 1, or 2) and the second between 0 and 39
* inclusive.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
if (oid.length < 2) {
throw new ASN1Exception("less than 2 components, violates X.208");
}
if (oid[0] < 0 || 2 < oid[0]) {
throw new ASN1Exception("First component invalid, value = " + oid[0]);
}
if (oid[1] < 0 || 39 < oid[1]) {
throw new ASN1Exception("Second component invalid, value = " + oid[1]);
}
int numBytes = 1;
for (int index = 2; index < oid.length; index++) {
int tmpValue = oid[index];
if (tmpValue < 0) {
throw new ASN1Exception("component " + (index + 1) +
" is negative, value = " + tmpValue);
}
do {
numBytes++;
tmpValue >>= 7;
} while (tmpValue != 0);
}
int[] octets = new int[numBytes];
octets[0] = (40 * oid[0]) + oid[1];
int bcount = 0;
for (int index = 2; index < oid.length; index++) {
int numberBytes = 0;
int tmpValue = oid[index];
do {
numberBytes++;
tmpValue >>= 7;
} while (tmpValue != 0);
tmpValue = oid[index];
for (int digit = numberBytes - 1; 0 <= digit; digit--) {
octets[++bcount] = (tmpValue >> (digit * 7)) & 0x7f;
if (digit != 0) {
octets[bcount] |= 0x80;
}
}
}
return new BERPrimitive(tagType, tag, octets);
}
/**
* Method to set the OBJECT IDENTIFIER's value.
*
* @param newVal the value to set the OBJECT IDENTIFIER to.
* @return this object identifier
*/
public ASN1ObjectIdentifier set(int[] newVal) {
oid = newVal;
return this;
}
/**
* Method to get the OBJECT IDENTIFIER's value. The returned value
* should not be modified in any way.
*
* @return the OBJECT IDENTIFIER's current value.
*/
public int[] get() {
return oid;
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder();
for (int index = 0; index < oid.length; index++) {
if (index != 0) {
str.append('.');
}
str.append(String.valueOf(oid[index]));
}
return new String(str);
}
}

View file

@ -0,0 +1,220 @@
package org.xbib.asn1;
import java.nio.charset.StandardCharsets;
/**
* Representation of an ASN.1 OCTET STRING.
* This class is used to store an ASN.1 OCTET STRING which is an
* arbitary string of octets (eight-bit values). An OCTET STRING
* can have any length including zero. The type is a string type.
*/
public class ASN1OctetString extends ASN1Any {
/**
* This constant is the ASN.1 UNIVERSAL tag value for OCTET STRING.
*/
public static final int OCTET_STRING_TAG = 0x04;
private static final char[] oct = {'0', '1', '2', '3', '4', '5', '6', '7'};
private static final char[] hex = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
/**
* The values of the OCTET STRING are stored in this string. Only
* the lower bytes are valid.
*/
private byte[] octets;
/**
* Constructor for an OCTET STRING object. The tag is set to the
* default of UNIVERSAL 4, and its value to the given bytes.
* @param data data
*/
public ASN1OctetString(byte[] data) {
octets = new byte[data.length];
System.arraycopy(data, 0, octets, 0, data.length);
}
/**
* Constructor for an OCTET STRING object. The tag is set to the
* default of UNIVERSAL 4, and its value to the lower bytes of the
* characters of the given string.
* @param str string
*/
public ASN1OctetString(String str) {
octets = str.getBytes(StandardCharsets.ISO_8859_1);
}
/**
* Constructor for a OCTET STRING object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1OctetString(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Does nothing for ASN1Any.
* @throws ASN1EncodingException If the BER cannot be decoded.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1EncodingException {
if (checkTag && (berEncoding.tagGet() != OCTET_STRING_TAG ||
berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + berEncoding.tagGet() +
" expected " + OCTET_STRING_TAG + "\n");
}
if (berEncoding instanceof BERPrimitive) {
BERPrimitive ber = (BERPrimitive) berEncoding;
int[] encoding = ber.peek();
StringBuilder buf = new StringBuilder(encoding.length);
for (int anEncoding : encoding) {
buf.append((char) (anEncoding & 0x00ff));
}
octets = buf.toString().getBytes(StandardCharsets.ISO_8859_1);
} else {
throw new ASN1EncodingException("decode from constructed NOT IMPLEMENTED YET");
}
}
/**
* Makes a BER encoding of the OCTET STRING.
* OCTET STRINGs can have a primitive encoding and a constructed
* encoding. This implemented performs the primitive encoding (which
* is the DER form).
*
* @return The BER encoding of the OCTET STRING
* @throws ASN1Exception when the OCTET STRING is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, OCTET_STRING_TAG);
}
/**
* Makes a BER encoding of the OCTET STRING.
* OCTET STRINGs can have a primitive encoding and a constructed
* encoding. This implemented performs the primitive encoding (which
* is the DER form).
*
* @return The BER encoding of the OCTET STRING
* @throws ASN1Exception when the OCTET STRING is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int size = octets.length;
int[] encoding = new int[size];
for (int index = 0; index < size; index++) {
encoding[index] = octets[index] & 0x00ff;
}
return new BERPrimitive(tagType, tag, encoding);
}
/**
* Method to set the OCTET STRING's value.
*
* @param octetArray the value to set the OCTET STRING to.
* @return the object.
*/
public ASN1OctetString set(byte[] octetArray) {
octets = new byte[octetArray.length];
System.arraycopy(octetArray, 0, octets, 0, octetArray.length);
return this;
}
/**
* Method to set the OCTET STRING's value.
*
* @param str the value to set the OCTET STRING to.
* @return the object.
*/
public ASN1OctetString set(String str) {
octets = str.getBytes(StandardCharsets.ISO_8859_1);
return this;
}
/**
* Method to get the OCTET STRING's value as a String.
*
* @return the OCTET STRING's current value.
*/
public String get() {
return new String(octets, StandardCharsets.ISO_8859_1);
}
/**
* Method to get the OCTET STRING's value as an array of bytes.
*
* @return the OCTET STRING's current value.
*/
public byte[] getBytes() {
return octets;
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
int size = octets.length;
StringBuilder buf = new StringBuilder(32 + (size * 4));
int printable = 0;
int binary = 0;
for (byte octet1 : octets) {
char octet = (char) octet1;
if ((' ' <= octet && octet <= '~') || octet == '\n') {
printable++;
} else {
binary++;
}
}
if (binary <= printable) {
buf.append('"');
for (byte octet1 : octets) {
char octet = (char) octet1;
if (' ' <= octet && octet <= '~') {
if (octet == '\\' || octet == '"' || octet == '\'') {
buf.append('\\');
}
buf.append(octet);
} else if (octet == '\n') {
buf.append("\\n");
} else if (octet == '\t') {
buf.append("\\t");
} else if (octet == '\r') {
buf.append("\\r");
} else if (octet == '\b') {
buf.append("\\b");
} else if (octet == '\f') {
buf.append("\\f");
} else {
buf.append('\\');
buf.append(oct[(octet >> 6) & 0x07]);
buf.append(oct[(octet >> 3) & 0x07]);
buf.append(oct[octet & 0x07]);
}
}
buf.append('"');
} else {
buf.append('\'');
for (byte octet1 : octets) {
char octet = (char) octet1;
buf.append(hex[(octet >> 4) & 0x0f]);
buf.append(hex[octet & 0x0f]);
}
buf.append("'H");
}
return buf.toString();
}
}

View file

@ -0,0 +1,57 @@
package org.xbib.asn1;
/**
* Representation for ASN.1 PrintableString.
* The <code>PrintableString</code> type denotes an arbitary string
* of printable characters from the following character set:
* <table>
* <caption>Printable Strings</caption>
* <tr><td>Capital letters<td>A, B, ... , Z
* <tr><td>Small letters<td>a, b, ..., z
* <tr><td>Digits<td>0, 1, ..., 9
* <tr><td>Space<td>
* <tr><td>Apostrophe<td>'
* <tr><td>Left partnthesis<td>(
* <tr><td>Right partnthesis<td>)
* <tr><td>Plus<td>+
* <tr><td>comma<td>,
* <tr><td>hyphen<td>-
* <tr><td>Full stop<td>.
* <tr><td>Solidus<td>/
* <tr><td>Colon<td>:
* <tr><td>Equal sign<td>=
* <tr><td>Question mark<td>?
* </table>
* This type is a string type.
*/
public final class ASN1PrintableString extends ASN1OctetString {
/**
* This constant is the ASN.1 UNIVERSAL tag value for PrintableString.
*/
public static final int PRINTABLE_STRING_TAG = 0x13;
/**
* Constructor for a PrintableString object. It sets the tag to the
* default value of UNIVERSAL 19 (0x13).
* @param text text
*/
public ASN1PrintableString(String text) {
super(text);
}
/**
* Constructor for a PrintableString object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1PrintableString(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != PRINTABLE_STRING_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("ASN.1 PrintableString: bad BER: tag=" + ber.tagGet() +
" expected " + PRINTABLE_STRING_TAG + "\n");
}
}
}

View file

@ -0,0 +1,138 @@
package org.xbib.asn1;
/**
* Representation of an ASN.1 SEQUENCE.
* The <code>SEQUENCE</code> type denotes an ordered collection
* of one or more types. The SEQUENCE OF type denotes an ordered
* collection of zero or more occurances of a given type.
* This class is available for the generic handling of ASN.1
* definitions. However, specialised ASN.1 productions will usually
* use their own encoding for SEQUENCES directly.
*/
public final class ASN1Sequence extends ASN1Any {
/**
* This constant tag value is the ASN.1 UNIVERSAL tag value for
* a SEQUENCE or a SEQUENCE OF type.
*/
public static final int SEQUENCE_TAG = 0x10;
/**
* The values of the SEQUENCE are stored in this array.
*/
private ASN1Any[] elements;
/**
* Default constructor for an ASN.1 SEQUENCE object. The tag is set
* to the default value.
*
* @param elementArray the ASN.1 objects that make up the sequence.
*/
public ASN1Sequence(ASN1Any[] elementArray) {
elements = elementArray;
}
/**
* Constructor for an ASN.1 SEQUENCE object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1Sequence(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1Exception {
if (checkTag && (berEncoding.tagGet() != SEQUENCE_TAG || berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException
("ASN.1 SEQUENCE: bad BER: tag=" + berEncoding.tagGet() +
" expected " + SEQUENCE_TAG + "\n");
}
if (berEncoding instanceof BERPrimitive) {
throw new ASN1EncodingException("ASN.1 SEQUENCE: bad form, primitive");
}
BERConstructed ber = (BERConstructed) berEncoding;
int len = ber.numberComponents();
elements = new ASN1Any[len];
for (int x = 0; x < len; x++) {
elements[x] = ASN1Decoder.toASN1(ber.elementAt(x));
}
}
/**
* Returns a BER encoding with no implicit tag.
*
* @return The BER encoding
* @throws ASN1Exception when the object is invalid and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, SEQUENCE_TAG);
}
/**
* Returns a BER encoding of the SEQUENCE implcitly tagged.
*
* @param tagType The type of the implcit tag
* @param tag The implicit tag number
* @return The BER encoding of the SEQUENCE
* @throws ASN1Exception when the SEQUENCE is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int len = elements.length;
BEREncoding[] encodings = new BEREncoding[len];
for (int index = 0; index < len; index++) {
encodings[index] = elements[index].berEncode();
}
return new BERConstructed(tagType, tag, encodings);
}
/**
* Method to set the SEQUENCE's elements.
*
* @param elementArray an array of ASN.1 object
* @return ASN.1 sequence
*/
public ASN1Sequence set(ASN1Any[] elementArray) {
elements = elementArray;
return this;
}
/**
* Method to get the elements of the SEQUENCE.
*
* @return an array containing the SEQUENCE's elements.
*/
public ASN1Any[] get() {
return elements;
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder("{");
for (int index = 0; index < elements.length; index++) {
if (index != 0) {
str.append(", ");
}
str.append(elements[index].toString());
}
str.append('}');
return new String(str);
}
}

View file

@ -0,0 +1,138 @@
package org.xbib.asn1;
/**
* Representation of an ASN.1 SET.
* The <code>SET</code> type denotes an ordered collection
* of one or more types. The SET OF type denotes an ordered
* collection of zero or more occurances of a given type.
* This class is available for the generic handling of ASN.1
* definitions. However, specialised ASN.1 productions will usually
* use their own encoding for SETs directly.
* For DER encoding, DEFAULTs are not included and all the elements
* are sorted according to tag number.
*/
public final class ASN1Set extends ASN1Any {
/**
* This constant value is the ASN.1 UNIVERSAL tag value indicating
* a SET or a SET OF type.
*/
public static final int SET_TAG = 0x11;
/**
* The values of the SET are stored in this array.
*/
private ASN1Any[] elements;
/**
* Constructor for an ASN.1 SET object. The tag is set to the
* default of UNIVERSAL 17 (0x11) and the elements to the given array.
*
* @param elementArray Elements in the set.
*/
public ASN1Set(ASN1Any[] elementArray) {
elements = elementArray;
}
/**
* Constructor for a SET object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1Set(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Method for initializing the object from a BER encoding.
*
* @param berEncoding The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
@Override
public void berDecode(BEREncoding berEncoding, boolean checkTag)
throws ASN1Exception {
if (checkTag && (berEncoding.tagGet() != SET_TAG ||
berEncoding.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + berEncoding.tagGet() +
" expected " + SET_TAG + "\n");
}
if (berEncoding instanceof BERPrimitive) {
throw new ASN1EncodingException("bad form, primitive");
}
BERConstructed ber = (BERConstructed) berEncoding;
int len = ber.numberComponents();
elements = new ASN1Any[len];
for (int x = 0; x < len; x++) {
elements[x] = ASN1Decoder.toASN1(ber.elementAt(x));
}
}
/**
* Returns a BER encoding of the SET.
*
* @return The BER encoding of the SET
* @throws ASN1Exception when the SET is invalid and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, SET_TAG);
}
/**
* Returns a BER encoding of the SET.
*
* @param tagType The type of the implcit tag
* @param tag The implicit tag number
* @return The BER encoding of the SET
* @throws ASN1Exception when the SET is invalid and cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int len = elements.length;
BEREncoding[] encodings = new BEREncoding[len];
for (int index = 0; index < len; index++) {
encodings[index] = elements[index].berEncode();
}
return new BERConstructed(tagType, tag, encodings);
}
/**
* Method to set the SET's elements.
*
* @param elementArray an array of ASN.1 objects.
*/
public void set(ASN1Any[] elementArray) {
elements = elementArray;
}
/**
* Method to get the elements of the SET.
*
* @return an array containing the SET's elements.
*/
public ASN1Any[] get() {
return elements;
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder("{");
for (int index = 0; index < elements.length; index++) {
if (index != 0) {
str.append(", ");
}
str.append(elements[index].toString());
}
str.append('}');
return new String(str);
}
}

View file

@ -0,0 +1,44 @@
package org.xbib.asn1;
/**
* Representation for ASN.1 T61String.
* The <code>T61String</code> type denotes an arbitary string
* of T.61 characters, or TeletextString. T.61 is an eight-bit extension
* to the ASCII character set. Special escape sequences specify the
* interpretation of subsequent character values (e.g. as
* Japanese rather than Latin). A T61String value can be of
* any length, including zero. This type is a string type.
*/
public final class ASN1T61String extends ASN1OctetString {
/**
* This constant is the UNIVERSAL tag value for T61String.
*/
public static final int T61_STRING_TAG = 0x14;
/**
* Constructor for an T61String object. It sets the tag to the
* default value of UNIVERSAL 20 (0x14).
*
* @param value The string value.
*/
public ASN1T61String(String value) {
super(value);
}
/**
* Constructor for a T61String object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1T61String(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != T61_STRING_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException
("ASN.1 T61String: bad BER: tag=" + ber.tagGet() +
" expected " + T61_STRING_TAG + "\n");
}
}
}

View file

@ -0,0 +1,62 @@
package org.xbib.asn1;
/**
* ASN.1 UTCTime.
* The <code>UTCTime</code> type denotes a "coordinated universal time"
* or Greenwich Mean Time (GMT) value. The value includes the local
* time precise to either minutes or seconds, and an offset from GMT
* in hours and minutes.
* It can take any of the following form:
* YYMMDDhhmmZ
* YYMMDDhhmm+hh'mm'
* YYMMDDhhmm-hh'mm'
* YYMMDDhhmmssZ
* YYMMDDhhmmss+hh'mm'
* YYMMDDhhmmss-hh'mm'
* YYMMDDhhmmZ
* YYMMDDhhmmZ
*/
public final class ASN1UTCTime extends ASN1VisibleString {
/**
* This constant is the UNIVERSAL tag value for UTCTime.
*/
public static final int UTC_TIME_TAG = 0x17;
/**
* Constructor for an UTCTime object. It sets the tag to the
* default value of UNIVERSAL 23 (0x17).
*
* @param value The string value.
*/
public ASN1UTCTime(String value) {
super(value);
}
/**
* Constructor for a UTCTime object from a BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1UTCTime(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != UTC_TIME_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException
("ASN.1 UTCTime: bad BER: tag=" + ber.tagGet() +
" expected " + UTC_TIME_TAG + "\n");
}
}
/**
* Returns a BER encoding with no implicit tag.
*
* @return The BER encoding
* @throws ASN1Exception when the object is invalid and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, UTC_TIME_TAG);
}
}

View file

@ -0,0 +1,51 @@
package org.xbib.asn1;
/**
* Representation for an ASN.1 VideotexString.
* The <code>VideotexString</code> type denotes an arbitary string
* of Videotex characters.
* This type is a string type.
*/
public class ASN1VideotexString extends ASN1OctetString {
/**
* This constant is the ASN.1 UNIVERSAL tag value for VideotexString.
*/
public static final int VIDEOTEX_STRING_TAG = 0x15;
/**
* Constructor for an ASN.1 VideotexString object. It sets the tag to the
* default value of UNIVERSAL 15 (0x21).
* @param value value
*/
public ASN1VideotexString(String value) {
super(value);
}
/**
* Constructor for a VideotexString object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1VideotexString(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != VIDEOTEX_STRING_TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + ber.tagGet() +
" expected " + VIDEOTEX_STRING_TAG + "\n");
}
}
/**
* Returns a BER encoding with no implicit tag.
*
* @return The BER encoding
* @throws ASN1Exception when the object is invalid
* and cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, VIDEOTEX_STRING_TAG);
}
}

View file

@ -0,0 +1,52 @@
package org.xbib.asn1;
/**
* ASN.1 VisibleString.
* The <code>VisibleString</code> type denotes an arbitary string
* of Visible characters. It is also known as ISO646String, or
* InternationalString.
* This type is a string type.
*/
public class ASN1VisibleString extends ASN1OctetString {
/**
* This constant is the ASN.1 UNIVERSAL tag value for VisibleString.
*/
public static final int TAG = 0x1a;
/**
* Constructor for a VisibleString object. It sets the tag to the
* default value of UNIVERSAL 26 (0x1a).
* @param value value
*/
public ASN1VisibleString(String value) {
super(value);
}
/**
* Constructor for a VisibleString object from a primitive BER encoding.
*
* @param ber The BER encoding to use.
* @param checkTag If true, it checks the tag. Use false if is implicitly tagged.
* @throws ASN1Exception If the BER encoding is incorrect.
*/
public ASN1VisibleString(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, false);
if (checkTag && (ber.tagGet() != TAG || ber.tagTypeGet() != BEREncoding.UNIVERSAL_TAG)) {
throw new ASN1EncodingException("bad BER: tag=" + ber.tagGet() +
" expected " + TAG + "\n");
}
}
/**
* Encode with no explicit tag.
*
* @return The BER encoding
* @throws ASN1Exception If the BER encoding is incorrect.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, TAG);
}
}

View file

@ -0,0 +1,122 @@
package org.xbib.asn1;
import java.io.IOException;
import java.io.OutputStream;
/**
* BERConstructed.
* This class represents a BER encoded ASN.1 object which is
* constructed from component BER encodings.
* Generally it is used to store the BER encoding of constructed types
* (i.e. SEQUENCE, SEQUENCE OF, SET, and SET OF) The end-of-content
* octets, if required, must be added to the end of the elements by
* the creator.
*/
public class BERConstructed extends BEREncoding {
private BEREncoding[] contentElements;
/**
* Constructor for a non-primitive BEREncoding.
*
* @param asn1Class The tag type.
* @param tag The tag number.
* @param elements The components making up the constructed BER.
* @throws ASN1Exception If tag or tag type is invalid
* @see org.xbib.asn1.BEREncoding#UNIVERSAL_TAG
* @see org.xbib.asn1.BEREncoding#APPLICATION_TAG
* @see org.xbib.asn1.BEREncoding#CONTEXT_SPECIFIC_TAG
* @see org.xbib.asn1.BEREncoding#PRIVATE_TAG
*/
public BERConstructed(int asn1Class, int tag, BEREncoding[] elements)
throws ASN1Exception {
int contentLength = 0;
for (BEREncoding element : elements) {
contentLength += element.iTotalLength;
}
init(asn1Class, true, tag, contentLength);
contentElements = elements;
}
/**
* This method outputs the encoded octets for this object
* to the output stream.
* Note: the output is not flushed, so you <strong>must</strong> explicitly
* flush the output stream after calling this method to ensure that
* the data has been written out.
*
* @param dest OutputStream to write encoding to.
*/
@Override
public void output(OutputStream dest) throws IOException {
outputHead(dest);
for (BEREncoding contentElement : contentElements) {
contentElement.output(dest);
}
}
/**
* This method returns the number of BER encoded elements that this
* object is made up of to be returned.
* @return integer
*/
public int numberComponents() {
return contentElements.length;
}
/**
* This method allows the elements of the BER encoding to be examined.
*
* @param index - the index of the BER object required,
* it must be in the range, [0, numberComponents() - 1]
* @return BER encoding
*/
public BEREncoding elementAt(int index) {
return contentElements[index];
}
/**
* Returns a new String object representing this ASN.1 object's value.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder("[");
switch (iTagType) {
case BEREncoding.UNIVERSAL_TAG:
str.append("UNIVERSAL ");
break;
case BEREncoding.APPLICATION_TAG:
str.append("APPLICATION ");
break;
case BEREncoding.CONTEXT_SPECIFIC_TAG:
str.append("CONTEXT SPECIFIC ");
break;
case BEREncoding.PRIVATE_TAG:
str.append("PRIVATE ");
break;
default:
break;
}
str.append(String.valueOf(iTag)).append("]{");
for (int x = 0; x < contentElements.length; x++) {
if (x != 0) {
str.append(',');
}
str.append(contentElements[x].toString());
}
str.append('}');
return new String(str);
}
/**
* This protected method is used to implement the "get_encoding" method.
*/
@Override
protected int iEncodingGet(int offset, byte[] data) {
int i = iGetHead(offset, data);
for (BEREncoding contentElement : contentElements) {
i = contentElement.iEncodingGet(i, data);
}
return i;
}
}

View file

@ -0,0 +1,424 @@
package org.xbib.asn1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* This class represents a BER (Basic Encoding Rules) encoded ASN.1 object.
* This is an abstract base class from which there are two specific
* representations are used: primitive and constructed. This superclass
* is tightly coupled with its subclasses BERPrimitive and BERConstructed.
* The BER encoding is described in
* <em>Information technology -
* Open Systems Interconnection -
* Specification of basic encoding rules for Abstract Syntax Notation
* One (ASN.1)</em>
* AS 3626-1991
* ISO/IEC 8825:1990
*
* @see org.xbib.asn1.BERPrimitive
* @see org.xbib.asn1.BERConstructed
*/
public abstract class BEREncoding {
private static final String ERROR = "Unexpected end in BER encoding";
/**
* Constant for indicating UNIVERSAL tag type. The value matches
* the BER bit encoding. Universal tags are for types defined in
* the ASN.1 standard.
*/
public static final int UNIVERSAL_TAG = 0x00;
/**
* Constant for indicating APPLICATION tag type. The value matches
* the BER bit encoding. APPLICATION tags are globally unique to an
* application.
*/
public static final int APPLICATION_TAG = 0x40;
/**
* Constant for indicating CONTEXT SPECIFIC tag type. The value matches
* the BER bit encoding. CONTEXT SPECIFIC tags are used in applications,
* but do not have to be globally unique.
*/
public static final int CONTEXT_SPECIFIC_TAG = 0x80;
/**
* Constant for indicating PRIVATE tag type. The value matches
* the BER bit encoding.
*/
public static final int PRIVATE_TAG = 0xC0;
private static final int MAX_BER_SIZE = 65536 * 4;
/**
* The tag type of this BER encoded object. This value must be
* the same as that encoded in the identiferEncoding.
* This is an internal member. You should not use this.
*/
protected int iTagType;
/**
* The tag number of this BER encoded object. This value must be
* the same as that encoded in the identiferEncoding.
* This is an internal member. You should not use this.
*/
protected int iTag;
/**
* The total length of this BER object (the identifier octets, plus
* length octets, plus content octects). This variable must be
* set up before this object is used (using the init method).
* This is an internal member. You should not use this.
*/
protected int iTotalLength;
/**
* Storage for the identifier octets. This variable is set up by
* calling the make_identifer method.
* The octets are internally stored as int[] for efficiency over byte[].
*/
private int[] identifierEncoding;
/**
* Storage for the length encoding octets. This will be set up by
* calling the makeLength method.
* The octets are internally stored as int[] for efficiency over byte[].
*/
private int[] lengthEncoding;
/**
* The public wrapping for doInput() method.
*
* @param inputStream the InputStream to read the raw BER from.
* @return Returns the next complete BEREncoding object read
* in from the input stream. Returns null if the
* end has been reached.
* @throws ASN1Exception If data does not represent a BER encoding
* @throws IOException On input I/O error
*/
public static BEREncoding input(InputStream inputStream) throws IOException {
int[] numBytesRead = new int[1];
numBytesRead[0] = 0;
return doInput(inputStream, numBytesRead);
}
/**
* Constructs a complete BER encoding object from octets read in from
* an InputStream.
* This routine handles all forms of encoding, including the
* indefite-length method. The length is always known with this
* class. With indefinite-length encodings,
* the end-of-contents octets are not included in the returned
* object (i.e. the returned the raw BER is converted to an object
* which is in the definite-length form).
*
* @param numBytesRead a counter for all read bytes.
* @param inputStream the InputStream to read the raw BER from.
* @return the next complete BEREncoding object read
* in from the input stream. Returns null if the
* end has been reached.
* @throws IOException If data does not represent a BER encoding or input I/O error
*/
protected static BEREncoding doInput(InputStream inputStream, int[] numBytesRead) throws IOException {
int octet = inputStream.read();
if (octet < 0) {
return null;
}
numBytesRead[0]++;
int tagType = octet & 0xC0;
boolean isCons = false;
if ((octet & 0x20) != 0) {
isCons = true;
}
int tag = octet & 0x1F;
if (tag == 0x1F) {
tag = 0;
do {
octet = inputStream.read();
if (octet < 0) {
throw new ASN1EncodingException(ERROR);
}
numBytesRead[0]++;
tag <<= 7;
tag |= (octet & 0x7F);
} while ((octet & 0x80) != 0);
}
int length;
octet = inputStream.read();
if (octet < 0) {
throw new ASN1EncodingException(ERROR);
}
numBytesRead[0]++;
if ((octet & 0x80) != 0) {
if ((octet & 0x7f) == 0) {
length = -1;
if (!isCons) {
throw new ASN1EncodingException("BER encoding corrupted primitive");
}
} else {
if (4 < (octet & 0x7f)) {
throw new ASN1EncodingException("BER encoding too long");
}
length = 0;
for (int numBytes = octet & 0x7f; 0 < numBytes; numBytes--) {
octet = inputStream.read();
if (octet < 0) {
throw new ASN1EncodingException(ERROR);
}
numBytesRead[0]++;
length <<= 8;
length |= (octet & 0xff);
}
if (length < 0 || MAX_BER_SIZE < length) {
throw new ASN1EncodingException("BER encoding too long");
}
}
} else {
length = octet & 0x7F;
}
if (!isCons) {
int[] contents = new int[length];
for (int x = 0; x < length; x++) {
octet = inputStream.read();
if (octet < 0) {
throw new ASN1EncodingException(ERROR);
}
numBytesRead[0]++;
contents[x] = octet;
}
return new BERPrimitive(tagType, tag, contents);
} else {
List<BEREncoding> chunks = new ArrayList<>();
int totalRead = 0;
if (0 <= length) {
while (totalRead < length) {
int currentRead = numBytesRead[0];
BEREncoding chunk = BEREncoding.doInput(inputStream, numBytesRead);
if (chunk == null) {
throw new ASN1EncodingException(ERROR);
}
chunks.add(chunk);
totalRead += numBytesRead[0] - currentRead;
}
} else {
while (true) {
BEREncoding chunk = BEREncoding.doInput(inputStream, numBytesRead);
if (chunk == null) {
throw new ASN1EncodingException(ERROR);
}
if (chunk.iTag == 0 && chunk.iTagType == BEREncoding.UNIVERSAL_TAG && chunk.iTotalLength == 2) {
break;
} else {
chunks.add(chunk);
}
}
}
int numElements = chunks.size();
BEREncoding[] parts = new BEREncoding[numElements];
for (int x = 0; x < numElements; x++) {
parts[x] = chunks.get(x);
}
return new BERConstructed(tagType, tag, parts);
}
}
/**
* Outputs the BER object to an OutputStream. This method should work
* with any OutputStream, whether it is from a socket, file, etc.
* Note: the output is not flushed, so you <strong>must</strong> explicitly
* flush the output stream after calling this method to ensure that
* the data has been written out.
*
* @param dest - the OutputStream to write the encoding to.
* @throws IOException On output I/O error
*/
public abstract void output(OutputStream dest) throws IOException;
/**
* Returns the BER encoded object as an array of bytes. This routine
* may be of use if you want to use the encoding rather than sending
* it off. If you want to just output it, it is more efficient to
* use the output method.
* @return byte array
*/
public byte[] encodingGet() {
byte[] result = new byte[iTotalLength];
iEncodingGet(0, result);
return result;
}
/**
* Method to examine the tag type of the BER encoded ASN.1 object.
* @return integer
*/
public int tagTypeGet() {
return iTagType;
}
/**
* Method to examine the tag number of the BER encoded ASN.1 object.
* @return integer
*/
public int tagGet() {
return iTag;
}
/**
* Returns the total number of bytes the encoding occupies.
* @return integer
*/
public int totalLength() {
return iTotalLength;
}
/**
* This is the initialization method used by the subclasses.
* The length must be the total length of the encoding of the
* contents (i.e. not including the identifier or length encodings).
*
* @param tagType The tag type.
* @param isConstructed True if constructed, or false if primitive.
* @param tag The tag number.
* @param length length
* @throws ASN1Exception if tag or tag type is invalid
*/
protected void init(int tagType, boolean isConstructed, int tag, int length)
throws ASN1Exception {
makeIdentifier(tagType, isConstructed, tag);
makeLength(length);
iTotalLength = identifierEncoding.length + lengthEncoding.length + length;
}
/*
* This is a protected routine used for outputting an array of
* integers, interpreted as bytes, to an OutputStream. It is used
* by the superclasses to implement the "output" method.
*/
protected void outputBytes(int[] data, OutputStream dest) throws IOException {
for (int aData : data) {
dest.write(aData);
}
}
/*
* This is a protected method used to output the encoded identifier
* and length octets to an OutputStream. It is used by the superclasses
* to implement the "output" method.
*/
protected void outputHead(OutputStream dest) throws IOException {
outputBytes(identifierEncoding, dest);
outputBytes(lengthEncoding, dest);
}
/*
* Internal protected method fills in the data array (starting from index
* position offset) with the encoding for the identifier and length.
* This is used by the superclasses to implement the "encodingGet"
* method.
*/
protected int iGetHead(int offset, byte[] data) {
for (int anIdentifierEncoding : identifierEncoding) {
data[offset++] = (byte) anIdentifierEncoding;
}
for (int aLengthEncoding : lengthEncoding) {
data[offset++] = (byte) aLengthEncoding;
}
return offset;
}
/*
* This is an abstract method used for implementing the "getEncoding"
* method. This method places the bytes of the encoding into the data
* array (as bytes), starting at offset into the array. The
* offset of the last element used plus one is returned.
*/
protected abstract int iEncodingGet(int offset, byte[] data);
/**
* This private method encodes the identifier octets. When a BER
* object is created, this method should be used to set up the encoding
* of the identifier, called via the "init" method.
* This method sets the internal variables "iTagType" and "iTag"
* so this object can be queried for the tag type and tag value without
* needing to decode them from the encoding octets.
*
* @param tagType is the tag type of the object, which
* must be one of the special value defined in ASN1_Any
* @param isConstructed is a boolean flag: true indicating the
* contents is constructed, or false indicating it is primitive.
* @param tag is the value of the tag, which must be non-negative.
* @throws ASN1Exception when the tagType is improper, or
* the tag value is negative.
*/
private void makeIdentifier(int tagType, boolean isConstructed, int tag)
throws ASN1Exception {
int b;
if ((tagType & ~0x00C0) != 0) {
throw new ASN1Exception("Invalid ASN.1 tag type");
}
if (tag < 0) {
throw new ASN1Exception("ASN.1 tag value is negative");
}
iTagType = tagType & 0xC0;
b = iTagType;
if (isConstructed) {
b |= 0x20;
}
iTag = tag;
if (tag <= 30) {
b |= (tag & 0x1F);
identifierEncoding = new int[1];
identifierEncoding[0] = b;
} else {
b |= 0x1F;
int numberBytes = 1;
int tmpTag = tag;
do {
numberBytes++;
tmpTag >>= 7;
} while (tmpTag != 0);
identifierEncoding = new int[numberBytes];
identifierEncoding[0] = b;
int index = 0;
for (int digit = numberBytes - 2; 0 <= digit; digit--) {
identifierEncoding[++index] = (tag >> (digit * 7)) & 0x7f;
if (digit != 0) {
identifierEncoding[index] |= 0x80;
}
}
}
}
/**
* This private method encodes the length octets. When a BER object
* is created, this method should be used to set up the encoding
* of the identifier. It should be used by calling the "init" method.
*
* @param length is the length value to be encoded. A negative
* value indicates an "indefinite length".
*/
private void makeLength(int length) {
if (length < 0) {
lengthEncoding = new int[1];
lengthEncoding[0] = 0x80;
} else if (length < 128) {
lengthEncoding = new int[1];
lengthEncoding[0] = length;
} else {
int count = 0;
int shifted = length;
while (shifted != 0) {
count++;
shifted >>= 8;
}
lengthEncoding = new int[count + 1];
lengthEncoding[0] = count | 0x80;
int index = 0;
while (0 < count) {
count--;
int digit = (length >> (count * 8)) & 0xff;
lengthEncoding[++index] = digit;
}
}
}
}

View file

@ -0,0 +1,113 @@
package org.xbib.asn1;
import java.io.IOException;
import java.io.OutputStream;
/**
* This class represents a primitive ASN.1 object encoded
* according to the Basic Encoding Rules.
* <em>Information technology -
* Open Systems Interconnection -
* Specification of basic encoding rules for Abstract Syntax Notation
* One (ASN.1)</em>
* AS 3626-1991
* ISO/IEC 8825:1990
*
* @see org.xbib.asn1.BEREncoding
*/
public class BERPrimitive extends BEREncoding {
private static final char[] hex = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
/**
* The octets of the encoding are stored in this array.
* They are internally stored as int[] for efficiency over byte[].
*/
private int[] contentsOctets;
/**
* Constructor.
* Note that the contents is int[] because this is the internal
* representation, which can only be used by the ASN.1 standard object
* classes. It is not intended that higher level classes create
* BERPrimitives directly.
*
* @see org.xbib.asn1.BEREncoding#UNIVERSAL_TAG
* @see org.xbib.asn1.BEREncoding#APPLICATION_TAG
* @see org.xbib.asn1.BEREncoding#CONTEXT_SPECIFIC_TAG
* @see org.xbib.asn1.BEREncoding#PRIVATE_TAG
*/
BERPrimitive(int asn1Class, int tag, int[] contents)
throws ASN1Exception {
init(asn1Class, false, tag, contents.length);
contentsOctets = contents;
}
/**
* This method allows the content octets to be examined.
* Once again, only the ASN.1 standard objects should be using this.
*/
int[] peek() {
return contentsOctets;
}
/**
* This method outputs the encoded octets to the destination OutputStream.
* Note: the output is not flushed, so you <strong>must</strong> explicitly
* flush the output stream after calling this method to ensure that
* the data has been written out.
*
* @param dest - OutputStream to write encoding to.
*/
@Override
public void output(OutputStream dest) throws IOException {
outputHead(dest);
outputBytes(contentsOctets, dest);
}
/**
* Returns a new String object representing this BER encoded
* ASN.1 object's value.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder("[");
switch (iTagType) {
case BEREncoding.UNIVERSAL_TAG:
str.append("UNIVERSAL ");
break;
case BEREncoding.APPLICATION_TAG:
str.append("APPLICATION ");
break;
case BEREncoding.CONTEXT_SPECIFIC_TAG:
str.append("CONTEXT SPECIFIC ");
break;
case BEREncoding.PRIVATE_TAG:
str.append("PRIVATE ");
break;
default:
break;
}
str.append(String.valueOf(iTag)).append("] '");
for (int octet : contentsOctets) {
str.append(hex[(octet >> 4) & 0x0f]);
str.append(hex[octet & 0x0f]);
}
str.append("'H");
return str.toString();
}
/**
* This protected method is used to implement the "get_encoding" method.
*/
@Override
protected int iEncodingGet(int offset, byte[] data) {
int i = iGetHead(offset, data);
for (int contentsOctet : contentsOctets) {
data[i++] = (byte) contentsOctet;
}
return i;
}
}

View file

@ -0,0 +1,4 @@
/**
* Classes for ASN.1.
*/
package org.xbib.asn1;

80
build.gradle Normal file
View file

@ -0,0 +1,80 @@
plugins {
id "org.sonarqube" version '2.5'
id "io.codearte.nexus-staging" version "0.7.0"
}
printf "Host: %s\nOS: %s %s %s\nJVM: %s %s %s %s\nGroovy: %s\nGradle: %s\n" +
"Build: group: ${project.group} name: ${project.name} version: ${project.version}\n",
InetAddress.getLocalHost(),
System.getProperty("os.name"),
System.getProperty("os.arch"),
System.getProperty("os.version"),
System.getProperty("java.version"),
System.getProperty("java.vm.version"),
System.getProperty("java.vm.vendor"),
System.getProperty("java.vm.name"),
GroovySystem.getVersion(),
gradle.gradleVersion
subprojects {
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'signing'
apply plugin: 'findbugs'
apply plugin: 'pmd'
apply plugin: 'checkstyle'
apply plugin: 'jacoco'
repositories {
mavenCentral()
}
configurations {
wagon
}
dependencies {
testCompile 'junit:junit:4.12'
wagon 'org.apache.maven.wagon:wagon-ssh:2.12'
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:all,-fallthrough" << "-profile" << "compact1"
}
clean {
delete 'out'
}
test {
testLogging {
showStandardStreams = false
exceptionFormat = 'full'
}
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier 'javadoc'
}
artifacts {
archives sourcesJar, javadocJar
}
if (project.hasProperty('signing.keyId')) {
signing {
sign configurations.archives
}
}
apply from: "${rootProject.projectDir}/gradle/ext.gradle"
apply from: "${rootProject.projectDir}/gradle/publish.gradle"
apply from: "${rootProject.projectDir}/gradle/sonarqube.gradle"
}

View file

@ -0,0 +1,323 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- This is a checkstyle configuration file. For descriptions of
what the following rules do, please see the checkstyle configuration
page at http://checkstyle.sourceforge.net/config.html -->
<module name="Checker">
<module name="FileTabCharacter">
<!-- Checks that there are no tab characters in the file.
-->
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!-- Checks that FIXME is not used in comments. TODO is preferred.
-->
<property name="format" value="((//.*)|(\*.*))FIXME" />
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="RegexpSingleline">
<!-- Checks that TODOs are named. (Actually, just that they are followed
by an open paren.)
-->
<property name="format" value="((//.*)|(\*.*))TODO[^(]" />
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="JavadocPackage">
<!-- Checks that each Java package has a Javadoc file used for commenting.
Only allows a package-info.java, not package.html. -->
</module>
<!-- All Java AST specific tests live under TreeWalker module. -->
<module name="TreeWalker">
<!--
IMPORT CHECKS
-->
<module name="RedundantImport">
<!-- Checks for redundant import statements. -->
<property name="severity" value="error"/>
</module>
<module name="ImportOrder">
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<property name="groups" value="com,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
<property name="severity" value="error"/>
</module>
<module name="JavadocStyle">
<property name="severity" value="warning"/>
</module>
<!--
NAMING CHECKS
-->
<!-- Item 38 - Adhere to generally accepted naming conventions -->
<module name="PackageName">
<!-- Validates identifiers for package names against the
supplied expression. -->
<!-- Here the default checkstyle rule restricts package name parts to
seven characters, this is not in line with common practice at Google.
-->
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
<property name="severity" value="warning"/>
</module>
<module name="TypeNameCheck">
<!-- Validates static, final fields against the
expression "^[A-Z][a-zA-Z0-9]*$". -->
<metadata name="altname" value="TypeName"/>
<property name="severity" value="warning"/>
</module>
<module name="ConstantNameCheck">
<!-- Validates non-private, static, final fields against the supplied
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
<metadata name="altname" value="ConstantName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="false"/>
<property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
<message key="name.invalidPattern"
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
<property name="severity" value="warning"/>
</module>
<module name="StaticVariableNameCheck">
<!-- Validates static, non-final fields against the supplied
expression "^[a-z][a-zA-Z0-9]*_?$". -->
<metadata name="altname" value="StaticVariableName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
<property name="severity" value="warning"/>
</module>
<module name="MemberNameCheck">
<!-- Validates non-static members against the supplied expression. -->
<metadata name="altname" value="MemberName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<property name="severity" value="warning"/>
</module>
<module name="MethodNameCheck">
<!-- Validates identifiers for method names. -->
<metadata name="altname" value="MethodName"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
<property name="severity" value="warning"/>
</module>
<module name="ParameterName">
<!-- Validates identifiers for method parameters against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalFinalVariableName">
<!-- Validates identifiers for local final variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalVariableName">
<!-- Validates identifiers for local variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<!--
LENGTH and CODING CHECKS
-->
<module name="LineLength">
<!-- Checks if a line is too long. -->
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="128"/>
<property name="severity" value="error"/>
<!--
The default ignore pattern exempts the following elements:
- import statements
- long URLs inside comments
-->
<property name="ignorePattern"
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
default="^(package .*;\s*)|(import .*;\s*)|( *(\*|//).*https?://.*)$"/>
</module>
<module name="LeftCurly">
<!-- Checks for placement of the left curly brace ('{'). -->
<property name="severity" value="warning"/>
</module>
<module name="RightCurly">
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
the same line. e.g., the following example is fine:
<pre>
if {
...
} else
</pre>
-->
<!-- This next example is not fine:
<pre>
if {
...
}
else
</pre>
-->
<property name="option" value="same"/>
<property name="severity" value="warning"/>
</module>
<!-- Checks for braces around if and else blocks -->
<module name="NeedBraces">
<property name="severity" value="warning"/>
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
</module>
<module name="UpperEll">
<!-- Checks that long constants are defined with an upper ell.-->
<property name="severity" value="error"/>
</module>
<module name="FallThrough">
<!-- Warn about falling through to the next case statement. Similar to
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
some other variants which we don't publicized to promote consistency).
-->
<property name="reliefPattern"
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
<property name="severity" value="error"/>
</module>
<!--
MODIFIERS CHECKS
-->
<module name="ModifierOrder">
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
8.4.3. The prescribed order is:
public, protected, private, abstract, static, final, transient, volatile,
synchronized, native, strictfp
-->
</module>
<!--
WHITESPACE CHECKS
-->
<module name="WhitespaceAround">
<!-- Checks that various tokens are surrounded by whitespace.
This includes most binary operators and keywords followed
by regular or curly braces.
-->
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
<property name="severity" value="error"/>
</module>
<module name="WhitespaceAfter">
<!-- Checks that commas, semicolons and typecasts are followed by
whitespace.
-->
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
</module>
<module name="NoWhitespaceAfter">
<!-- Checks that there is no whitespace after various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
UNARY_PLUS"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="NoWhitespaceBefore">
<!-- Checks that there is no whitespace before various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="ParenPad">
<!-- Checks that there is no whitespace before close parens or after
open parens.
-->
<property name="severity" value="warning"/>
</module>
</module>
</module>

View file

@ -0,0 +1,7 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress checks="." files="[\\/]generated-src[\\/].*\.java$"/>
</suppressions>

5
gradle.properties Normal file
View file

@ -0,0 +1,5 @@
group = org.xbib
name = z3950
version = 1.0.0
xbib-cql.version = 1.1.0

8
gradle/ext.gradle Normal file
View file

@ -0,0 +1,8 @@
ext {
user = 'xbib'
projectName = 'z3950'
projectDescription = 'Z39.50 for Java'
scmUrl = 'https://github.com/xbib/z3950'
scmConnection = 'scm:git:git://github.com/xbib/z3950.git'
scmDeveloperConnection = 'scm:git:git://github.com/xbib/z3950.git'
}

70
gradle/publish.gradle Normal file
View file

@ -0,0 +1,70 @@
task xbibUpload(type: Upload, dependsOn: build) {
configuration = configurations.archives
uploadDescriptor = true
repositories {
if (project.hasProperty('xbibUsername')) {
mavenDeployer {
configuration = configurations.wagon
repository(url: uri('sftp://xbib.org/repository')) {
authentication(userName: xbibUsername, privateKey: xbibPrivateKey)
}
}
}
}
}
task sonatypeUpload(type: Upload, dependsOn: build) {
configuration = configurations.archives
uploadDescriptor = true
repositories {
if (project.hasProperty('ossrhUsername')) {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: uri(ossrhReleaseUrl)) {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
snapshotRepository(url: uri(ossrhSnapshotUrl)) {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
pom.project {
groupId project.group
artifactId project.name
version project.version
name project.name
description projectDescription
packaging 'jar'
inceptionYear '2017'
url scmUrl
organization {
name 'xbib'
url 'http://xbib.org'
}
developers {
developer {
id user
name 'Jörg Prante'
email 'joergprante@gmail.com'
url 'https://github.com/jprante'
}
}
scm {
url scmUrl
connection scmConnection
developerConnection scmDeveloperConnection
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
}
}
}
}
}
nexusStaging {
packageGroup = "org.xbib"
}

40
gradle/sonarqube.gradle Normal file
View file

@ -0,0 +1,40 @@
tasks.withType(FindBugs) {
ignoreFailures = true
reports {
xml.enabled = false
html.enabled = true
}
}
tasks.withType(Pmd) {
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
tasks.withType(Checkstyle) {
ignoreFailures = true
exclude '**/PQF*java'
reports {
xml.enabled = true
html.enabled = true
}
}
jacocoTestReport {
reports {
xml.enabled = true
csv.enabled = false
}
}
sonarqube {
properties {
property "sonar.projectName", "${project.group} ${project.name}"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.tests", "src/test/java"
property "sonar.scm.provider", "git"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.junit.reportsPath", "build/test-results/test/"
}
}

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,6 @@
#Mon Oct 09 13:24:07 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-all.zip

172
gradlew vendored Executable file
View file

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
gradlew.bat vendored Normal file
View file

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

4
settings.gradle Normal file
View file

@ -0,0 +1,4 @@
rootProject.name = name
include 'asn1'
include 'z3950'

9
z3950/build.gradle Normal file
View file

@ -0,0 +1,9 @@
plugins {
id 'org.xbib.gradle.plugin.jflex' version '1.1.0'
id 'org.xbib.gradle.plugin.jacc' version '1.1.3'
}
dependencies {
compile project(':asn1')
compile "org.xbib:cql:${project.property('xbib-cql.version')}"
}

View file

@ -0,0 +1,323 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- This is a checkstyle configuration file. For descriptions of
what the following rules do, please see the checkstyle configuration
page at http://checkstyle.sourceforge.net/config.html -->
<module name="Checker">
<module name="FileTabCharacter">
<!-- Checks that there are no tab characters in the file.
-->
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!-- Checks that FIXME is not used in comments. TODO is preferred.
-->
<property name="format" value="((//.*)|(\*.*))FIXME" />
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="RegexpSingleline">
<!-- Checks that TODOs are named. (Actually, just that they are followed
by an open paren.)
-->
<property name="format" value="((//.*)|(\*.*))TODO[^(]" />
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="JavadocPackage">
<!-- Checks that each Java package has a Javadoc file used for commenting.
Only allows a package-info.java, not package.html. -->
</module>
<!-- All Java AST specific tests live under TreeWalker module. -->
<module name="TreeWalker">
<!--
IMPORT CHECKS
-->
<module name="RedundantImport">
<!-- Checks for redundant import statements. -->
<property name="severity" value="error"/>
</module>
<module name="ImportOrder">
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<property name="groups" value="com.google,android,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
<property name="severity" value="error"/>
</module>
<module name="JavadocStyle">
<property name="severity" value="warning"/>
</module>
<!--
NAMING CHECKS
-->
<!-- Item 38 - Adhere to generally accepted naming conventions -->
<module name="PackageName">
<!-- Validates identifiers for package names against the
supplied expression. -->
<!-- Here the default checkstyle rule restricts package name parts to
seven characters, this is not in line with common practice at Google.
-->
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
<property name="severity" value="warning"/>
</module>
<module name="TypeNameCheck">
<!-- Validates static, final fields against the
expression "^[A-Z][a-zA-Z0-9]*$". -->
<metadata name="altname" value="TypeName"/>
<property name="severity" value="warning"/>
</module>
<module name="ConstantNameCheck">
<!-- Validates non-private, static, final fields against the supplied
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
<metadata name="altname" value="ConstantName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="false"/>
<property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
<message key="name.invalidPattern"
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
<property name="severity" value="warning"/>
</module>
<module name="StaticVariableNameCheck">
<!-- Validates static, non-final fields against the supplied
expression "^[a-z][a-zA-Z0-9]*_?$". -->
<metadata name="altname" value="StaticVariableName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
<property name="severity" value="warning"/>
</module>
<module name="MemberNameCheck">
<!-- Validates non-static members against the supplied expression. -->
<metadata name="altname" value="MemberName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<property name="severity" value="warning"/>
</module>
<module name="MethodNameCheck">
<!-- Validates identifiers for method names. -->
<metadata name="altname" value="MethodName"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
<property name="severity" value="warning"/>
</module>
<module name="ParameterName">
<!-- Validates identifiers for method parameters against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalFinalVariableName">
<!-- Validates identifiers for local final variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalVariableName">
<!-- Validates identifiers for local variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<!--
LENGTH and CODING CHECKS
-->
<module name="LineLength">
<!-- Checks if a line is too long. -->
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="128"/>
<property name="severity" value="error"/>
<!--
The default ignore pattern exempts the following elements:
- import statements
- long URLs inside comments
-->
<property name="ignorePattern"
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
default="^(package .*;\s*)|(import .*;\s*)|( *(\*|//).*https?://.*)$"/>
</module>
<module name="LeftCurly">
<!-- Checks for placement of the left curly brace ('{'). -->
<property name="severity" value="warning"/>
</module>
<module name="RightCurly">
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
the same line. e.g., the following example is fine:
<pre>
if {
...
} else
</pre>
-->
<!-- This next example is not fine:
<pre>
if {
...
}
else
</pre>
-->
<property name="option" value="same"/>
<property name="severity" value="warning"/>
</module>
<!-- Checks for braces around if and else blocks -->
<module name="NeedBraces">
<property name="severity" value="warning"/>
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
</module>
<module name="UpperEll">
<!-- Checks that long constants are defined with an upper ell.-->
<property name="severity" value="error"/>
</module>
<module name="FallThrough">
<!-- Warn about falling through to the next case statement. Similar to
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
some other variants which we don't publicized to promote consistency).
-->
<property name="reliefPattern"
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
<property name="severity" value="error"/>
</module>
<!--
MODIFIERS CHECKS
-->
<module name="ModifierOrder">
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
8.4.3. The prescribed order is:
public, protected, private, abstract, static, final, transient, volatile,
synchronized, native, strictfp
-->
</module>
<!--
WHITESPACE CHECKS
-->
<module name="WhitespaceAround">
<!-- Checks that various tokens are surrounded by whitespace.
This includes most binary operators and keywords followed
by regular or curly braces.
-->
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
<property name="severity" value="error"/>
</module>
<module name="WhitespaceAfter">
<!-- Checks that commas, semicolons and typecasts are followed by
whitespace.
-->
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
</module>
<module name="NoWhitespaceAfter">
<!-- Checks that there is no whitespace after various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
UNARY_PLUS"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="NoWhitespaceBefore">
<!-- Checks that there is no whitespace before various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="ParenPad">
<!-- Checks that there is no whitespace before close parens or after
open parens.
-->
<property name="severity" value="warning"/>
</module>
</module>
</module>

View file

@ -0,0 +1,24 @@
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<localRepository>~/.m2/repository</localRepository>
<activeProfiles>
<activeProfile>xbib</activeProfile>
</activeProfiles>
<profiles>
<profile>
<id>xbib</id>
<repositories>
<repository>
<id>xbib</id>
<url>http://xbib.org/repository</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>

View file

@ -0,0 +1 @@
%{ import java.io.Reader; import java.io.IOException; /** Mike Taylor, IndexData: "Prefix Query Format (PQF), also known as Prefix Query Notation (PQN) was defined in 1995, as part of the YAZ toolkit, and has since become the de facto standard representation of RPN queries." From: http://www.indexdata.com/yaz/doc/tools.tkl#PQF The grammar of the PQF is as follows: query ::= top-set query-struct. top-set ::= [ '@attrset' string ] query-struct ::= attr-spec | simple | complex | '@term' term-type query attr-spec ::= '@attr' [ string ] string query-struct complex ::= operator query-struct query-struct. operator ::= '@and' | '@or' | '@not' | '@prox' proximity. simple ::= result-set | term. result-set ::= '@set' string. term ::= string. proximity ::= exclusion distance ordered relation which-code unit-code. exclusion ::= '1' | '0' | 'void'. distance ::= integer. ordered ::= '1' | '0'. relation ::= integer. which-code ::= 'known' | 'private' | integer. unit-code ::= integer. term-type ::= 'general' | 'numeric' | 'string' | 'oid' | 'datetime' | 'null'. You will note that the syntax above is a fairly faithful representation of RPN, except for the Attribute, which has been moved a step away from the term, allowing you to associate one or more attributes with an entire query structure. The parser will automatically apply the given attributes to each term as required. The @attr operator is followed by an attribute specification (attr-spec above). The specification consists of an optional attribute set, an attribute type-value pair and a sub-query. The attribute type-value pair is packed in one string: an attribute type, an equals sign, and an attribute value, like this: @attr 1=1003. The type is always an integer but the value may be either an integer or a string (if it doesn't start with a digit character). A string attribute-value is encoded as a Type-1 ``complex'' attribute with the list of values containing the single string specified, and including no semantic indicators. */ %} %class PQFParser %interface PQFTokens %package org.xbib.io.iso23950.pqf %token NL %token <String> OR %token <String> AND %token <String> NOT %token <String> ATTR %token <String> ATTRSET %token <String> TERM %token <String> SET %token <String> VOID %token <String> KNOWN %token <String> PRIVATE %token <String> TERMTYPE %token <String> CHARSTRING1 %token <String> CHARSTRING2 %token <String> OPERATORS %token <String> EQUALS %token <Integer> INTEGER %left AND %left OR %left NOT %type <PQF> pqf %type <Query> querystruct %type <Expression> expression %type <AttrStr> attrstr %type <Term> term %type <Setname> resultset %start pqf %% pqf : ATTRSET CHARSTRING1 querystruct { this.pqf = new PQF($2, $3); $$ = this.pqf; } | querystruct { this.pqf = new PQF($1); $$ = this.pqf; } ; querystruct : attrspec | simple | complex | TERM TERMTYPE pqf { $$ = new Query($3); }; attrspec : ATTR attrstr querystruct { $$ = new Query($2, $3); } | ATTR CHARSTRING1 attrstr querystruct { $$ = new Query($2, $3, $4); }; simple : resultset { $$ = new Query($1); } | term { $$ = new Query($1); }; complex : expression { $$ = new Query($1); }; resultset : SET CHARSTRING1 { $$ = new Setname($2); }; term : CHARSTRING1 { $$ = new Term($1); } | CHARSTRING2 { $$ = new Term($1); } }; attrstr: INTEGER EQUALS INTEGER { $$ = new AttrStr($1, $3); } | INTEGER EQUALS CHARSTRING1 { $$ = new AttrStr($1, $3); }; expression: AND querystruct querystruct { $$ = new Expression($1, $2, $3); } | OR querystruct querystruct { $$ = new Expression($1, $2, $3); } | NOT querystruct querystruct { $$ = new Expression($1, $2, $3); } ; %% private PQFLexer lexer; private PQF pqf; public PQFParser(Reader r) { this.lexer = new PQFLexer(r); lexer.nextToken(); } public void yyerror(String error) { throw new SyntaxException("PQF error at " + "[" + lexer.getLine() + "," + lexer.getColumn() +"]" + ": " + error); } public PQF getResult() { return pqf; }

View file

@ -0,0 +1,59 @@
package org.xbib.io.iso23950;
import java.io.IOException;
import java.util.ResourceBundle;
/**
* Diagnostics for Z server.
*/
public class Diagnostics extends IOException {
private static final ResourceBundle bundle =
ResourceBundle.getBundle("org.xbib.io.iso23950.diagnostics");
private static final long serialVersionUID = -899201811019819079L;
private int diagCode;
private String message;
private String details;
public Diagnostics(int diagCode) {
super("" + diagCode);
this.diagCode = diagCode;
}
public Diagnostics(int diagCode, String message) {
super("" + diagCode + " " + message);
this.diagCode = diagCode;
this.message = message;
}
public Diagnostics(int diagCode, String message, String details) {
super("" + diagCode + " " + message + " " + details);
this.diagCode = diagCode;
this.message = message;
this.details = details;
}
public String getPlainText() {
String[] s = bundle.getString(Integer.toString(diagCode)).split("\\|");
if (message == null) {
message = s.length > 0 ? s[1] : "<undefined>";
}
if (details == null) {
details = s.length > 1 ? s[2] : "<undefined>";
}
StringBuilder sb = new StringBuilder();
sb.append("diag code=").append(diagCode)
.append(" message=").append(message)
.append(" details=").append(details);
return sb.toString();
}
@Override
public String toString() {
return getPlainText();
}
}

View file

@ -0,0 +1,11 @@
package org.xbib.io.iso23950;
/**
*
*/
public class ErrorRecord extends Record {
public ErrorRecord(int number, byte[] content) {
super(number, content);
}
}

View file

@ -0,0 +1,10 @@
package org.xbib.io.iso23950;
/**
*
*/
@FunctionalInterface
public interface InitListener {
void onInit(int version, String info);
}

View file

@ -0,0 +1,35 @@
package org.xbib.io.iso23950;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
/**
* A record for Z39.50 presentations.
*/
public class Record {
private final int number;
private final byte[] content;
private final ByteArrayInputStream stream;
public Record(int number, byte[] content) {
this.number = number;
this.content = content;
this.stream = new ByteArrayInputStream(content);
}
public int getNumber() {
return number;
}
public InputStream asStream() {
return stream;
}
public String toString(Charset charset) {
return new String(content, charset);
}
}

View file

@ -0,0 +1,10 @@
package org.xbib.io.iso23950;
/**
*
*/
@FunctionalInterface
public interface RecordListener {
void onRecord(Record record);
}

View file

@ -0,0 +1,12 @@
package org.xbib.io.iso23950;
import java.io.IOException;
/**
*
*/
@FunctionalInterface
public interface ResponseListener {
void onResponse(int status, int recordCount, long elapsedMillis) throws IOException;
}

View file

@ -0,0 +1,504 @@
package org.xbib.io.iso23950;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.BEREncoding;
import org.xbib.cql.CQLParser;
import org.xbib.io.iso23950.cql.CQLRPNGenerator;
import org.xbib.io.iso23950.operations.InitOperation;
import org.xbib.io.iso23950.operations.PresentOperation;
import org.xbib.io.iso23950.operations.SearchOperation;
import org.xbib.io.iso23950.pqf.PQFParser;
import org.xbib.io.iso23950.pqf.PQFRPNGenerator;
import org.xbib.io.iso23950.v3.Close;
import org.xbib.io.iso23950.v3.CloseReason;
import org.xbib.io.iso23950.v3.PDU;
import org.xbib.io.iso23950.v3.RPNQuery;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UncheckedIOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Default Z client.
*/
public class ZClient implements AutoCloseable {
private static final Logger logger = Logger.getLogger(ZClient.class.getName());
private final String host;
private final int port;
private final String user;
private final String pass;
private final long timeout;
private final String preferredRecordSyntax;
private final String resultSetName;
private final String elementSetName;
private final String encoding;
private final String format;
private final String type;
private final List<String> databases;
private final Socket socket;
private final BufferedInputStream src;
private final BufferedOutputStream dest;
public ZClient(String host, int port, String user, String pass, long timeout,
String preferredRecordSyntax,
String resultSetName,
String elementSetName,
String encoding,
String format,
String type,
List<String> databases,
Integer preferredMessageSize,
InitListener initListener) throws IOException {
this.host = host;
this.port = port;
this.user = user;
this.pass = pass;
this.timeout = timeout;
this.preferredRecordSyntax = preferredRecordSyntax;
this.resultSetName = resultSetName;
this.elementSetName = elementSetName;
this.encoding = encoding;
this.format = format;
this.type = type;
this.databases = databases;
Socket socket = new Socket();
socket.connect(new InetSocketAddress(host, port), (int) timeout);
socket.setSoTimeout((int) timeout * 1000);
this.socket = socket;
this.src = new BufferedInputStream(socket.getInputStream());
this.dest = new BufferedOutputStream(socket.getOutputStream());
// always send init operation after socket init
InitOperation init = new InitOperation();
if (init.execute(this, preferredMessageSize, initListener)) {
throw new IOException("could not initiatie connection");
}
}
public static ZClient newZClient(String name) throws IOException {
return newZClient(getProperties(name));
}
public static Properties getProperties(String name) throws IOException {
Properties properties = new Properties();
try (InputStream inputStream =
ZClient.class.getResourceAsStream("/org/xbib/io/iso23950/service/" + name + ".properties")) {
properties.load(inputStream);
}
return properties;
}
public static ZClient newZClient(Properties properties) throws IOException {
Builder builder = builder();
if (properties.containsKey("host")) {
builder.setHost(properties.getProperty("host"));
}
if (properties.containsKey("port")) {
builder.setPort(Integer.parseInt(properties.getProperty("port")));
}
if (properties.containsKey("user")) {
builder.setUser(properties.getProperty("user"));
}
if (properties.containsKey("pass")) {
builder.setPass(properties.getProperty("pass"));
}
if (properties.containsKey("database")) {
builder.setDatabases(Collections.singletonList(properties.getProperty("database")));
}
if (properties.containsKey("elementsetname")) {
builder.setElementSetName(properties.getProperty("elementsetname"));
}
if (properties.containsKey("preferredrecordsyntax")) {
builder.setPreferredRecordSyntax(properties.getProperty("preferredrecordsyntax"));
}
if (properties.containsKey("resultsetname")) {
builder.setResultSetName(properties.getProperty("resultsetname"));
}
if (properties.containsKey("encoding")) {
builder.setEncoding(properties.getProperty("encoding"));
}
if (properties.containsKey("format")) {
builder.setFormat(properties.getProperty("format"));
}
if (properties.containsKey("type")) {
builder.setType(properties.getProperty("type"));
}
return builder.build();
}
public boolean isConnected() {
return socket != null && socket.isConnected();
}
@Override
public void close() throws IOException {
if (isConnected()) {
try {
sendClose(0);
} catch (IOException e) {
logger.log(Level.WARNING, "while attempting to close connection: {}", e.getMessage());
}
try {
if (src != null) {
src.close();
}
} catch (IOException e) {
logger.log(Level.WARNING, "error attempting to close connection: {}", e.getMessage());
}
try {
if (dest != null) {
dest.close();
}
} catch (IOException e) {
logger.log(Level.WARNING, "error attempting to close connection: {}", e.getMessage());
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
logger.log(Level.WARNING, "error attempting to close connection: {}", e.getMessage());
}
}
}
/**
* Send a close request to the server.
*
* @param reason reason Reason codes are:
* 0=finished 1=shutdown 2=system problem 3=cost limits
* 4=resources 5=security violation 6=protocol error 7=lack of activity
* 8=peer abort 9=unspecified
* @throws IOException if close fails
*/
public void sendClose(int reason) throws IOException {
PDU pdu = new PDU();
pdu.c_close = new Close();
pdu.c_close.sCloseReason = new CloseReason();
pdu.c_close.sCloseReason.value = new ASN1Integer(reason);
pdu.c_close.sReferenceId = null;
writePDU(pdu);
// do not wait, it may hang
//waitClosePDU();
}
public void writePDU(PDU pdu) throws IOException {
if (dest == null) {
throw new IOException("no output stream");
}
try {
pdu.berEncode().output(dest);
dest.flush();
} catch (ASN1Exception ex) {
throw new IOException(ex);
}
}
public PDU readPDU() throws IOException {
if (src == null) {
throw new IOException("no input");
}
try {
BEREncoding ber = BEREncoding.input(src);
if (ber == null) {
throw new IOException("read PDU error");
}
return new PDU(ber, true);
} catch (ASN1Exception ex) {
throw new IOException(ex);
} catch (NullPointerException ex) {
throw new IOException("connection read PDU error", ex);
}
}
public int executeCQL(String query, int offset, int length,
ResponseListener responseListener,
RecordListener recordListener) throws IOException {
if (query == null) {
throw new IllegalArgumentException("no query");
}
SearchOperation search = new SearchOperation();
boolean success = search.execute(this, createRPNQueryFromCQL(query));
if (!success) {
logger.log(Level.WARNING, MessageFormat.format("search was not a success [{0}]", query));
} else {
if (responseListener == null) {
responseListener = (status, recordCount, elapsedMillis) -> {
logger.log(Level.INFO, MessageFormat.format("[{0}ms] [{1}] [{2}]",
elapsedMillis, recordCount, query));
};
}
if (search.getCount() > 0) {
PresentOperation present = new PresentOperation();
if (offset < 1) {
// Z39.50 present bails out when offset = 0
offset = 1;
}
if (length > search.getCount()) {
// avoid condition 13 "Present request out-of-range"
length = search.getCount();
}
present.execute(this, offset, length, responseListener, recordListener);
}
}
return search.getCount();
}
public int executePQF(String query, int offset, int length,
ResponseListener responseListener,
RecordListener recordListener) throws IOException {
if (query == null) {
throw new IllegalArgumentException("no query");
}
SearchOperation search = new SearchOperation();
search.execute(this, createRPNQueryFromPQF(query));
if (!search.isSuccess()) {
logger.log(Level.WARNING, MessageFormat.format("search was not a success [{0}]", query));
} else {
if (responseListener == null) {
responseListener = (status, recordCount, elapsedMillis) -> {
logger.log(Level.INFO, MessageFormat.format("[{0}ms] [{1}] [{2}]",
elapsedMillis, recordCount, query));
};
}
if (search.getCount() > 0) {
logger.log(Level.INFO, "search returned " + search.getCount());
PresentOperation present = new PresentOperation();
if (offset < 1) {
// Z39.50 bails out when offset = 0
offset = 1;
}
if (length > search.getCount()) {
// avoid condition 13 "Present request out-of-range"
length = search.getCount();
}
present.execute(this, offset, length, responseListener, recordListener);
}
}
return search.getCount();
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public String getUser() {
return user;
}
public String getPass() {
return pass;
}
public long getTimeout() {
return timeout;
}
public String getPreferredRecordSyntax() {
return preferredRecordSyntax;
}
public String getResultSetName() {
return resultSetName;
}
public String getElementSetName() {
return elementSetName;
}
public String getEncoding() {
return encoding;
}
public String getFormat() {
return format;
}
public String getType() {
return type;
}
public List<String> getDatabases() {
return databases;
}
public RPNQuery createRPNQueryFromCQL(String query) throws IOException {
CQLRPNGenerator generator = new CQLRPNGenerator();
CQLParser parser = new CQLParser(query);
parser.parse();
parser.getCQLQuery().accept(generator);
return generator.getQueryResult();
}
public RPNQuery createRPNQueryFromPQF(String query) throws IOException {
PQFRPNGenerator generator = new PQFRPNGenerator();
PQFParser parser = new PQFParser(new StringReader(query));
parser.parse();
parser.getResult().accept(generator);
return generator.getResult();
}
public static Builder builder() {
return new Builder();
}
/**
*
*/
public static class Builder {
private static final ResourceBundle recordSyntaxBundle =
ResourceBundle.getBundle("org.xbib.io.iso23950.recordsyntax");
private String host;
private int port;
private String user;
private String pass;
private long timeout;
private String preferredRecordSyntax = "1.2.840.10003.5.10"; // marc21
private String resultSetName = "default";
private String elementSetName = "F";
private String encoding = "ANSEL";
private String format = "MARC21";
private String type = "Bibliographic";
private List<String> databases = Collections.singletonList("");
private Integer preferredMessageSize = 1024 * 1024;
private InitListener initListener;
public Builder setHost(String host) {
this.host = host;
return this;
}
public Builder setPort(int port) {
this.port = port;
return this;
}
public Builder setUser(String user) {
this.user = user;
return this;
}
public Builder setPass(String pass) {
this.pass = pass;
return this;
}
public Builder setTimeout(long timeout) {
this.timeout = timeout;
return this;
}
public Builder setPreferredRecordSyntax(String preferredRecordSyntax) {
this.preferredRecordSyntax = preferredRecordSyntax;
if (recordSyntaxBundle.containsKey(preferredRecordSyntax)) {
this.preferredRecordSyntax = recordSyntaxBundle.getString(preferredRecordSyntax);
}
return this;
}
public Builder setResultSetName(String resultSetName) {
this.resultSetName = resultSetName;
return this;
}
public Builder setElementSetName(String elementSetName) {
this.elementSetName = elementSetName;
return this;
}
public Builder setEncoding(String encoding) {
this.encoding = encoding;
return this;
}
public Builder setFormat(String format) {
this.format = format;
return this;
}
public Builder setType(String type) {
this.type = type;
return this;
}
public Builder setDatabases(List<String> databases) {
this.databases = databases;
return this;
}
public Builder setPreferredMessageSize(int preferredMessageSize) {
this.preferredMessageSize = preferredMessageSize;
return this;
}
public Builder setInitListener(InitListener initListener) {
this.initListener = initListener;
return this;
}
public ZClient build() {
try {
return new ZClient(host, port, user, pass, timeout,
preferredRecordSyntax,
resultSetName,
elementSetName,
encoding,
format,
type,
databases,
preferredMessageSize,
initListener);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
}

View file

@ -0,0 +1,334 @@
package org.xbib.io.iso23950.cql;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1Null;
import org.xbib.asn1.ASN1ObjectIdentifier;
import org.xbib.asn1.ASN1OctetString;
import org.xbib.cql.BooleanGroup;
import org.xbib.cql.BooleanOperator;
import org.xbib.cql.Identifier;
import org.xbib.cql.Index;
import org.xbib.cql.Modifier;
import org.xbib.cql.ModifierList;
import org.xbib.cql.PrefixAssignment;
import org.xbib.cql.Query;
import org.xbib.cql.Relation;
import org.xbib.cql.ScopedClause;
import org.xbib.cql.SearchClause;
import org.xbib.cql.SimpleName;
import org.xbib.cql.SingleSpec;
import org.xbib.cql.SortSpec;
import org.xbib.cql.SortedQuery;
import org.xbib.cql.Term;
import org.xbib.cql.Visitor;
import org.xbib.io.iso23950.v3.AttributeElement;
import org.xbib.io.iso23950.v3.AttributeElementAttributeValue;
import org.xbib.io.iso23950.v3.AttributeList;
import org.xbib.io.iso23950.v3.AttributeSetId;
import org.xbib.io.iso23950.v3.AttributesPlusTerm;
import org.xbib.io.iso23950.v3.Operand;
import org.xbib.io.iso23950.v3.Operator;
import org.xbib.io.iso23950.v3.RPNQuery;
import org.xbib.io.iso23950.v3.RPNStructure;
import org.xbib.io.iso23950.v3.RPNStructureRpnRpnOp;
import java.util.HashMap;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Stack;
/**
* This is a RPN (Type-1 query) generator for CQL queries.
*
* @see <a href="http://www.loc.gov/z3950/agency/markup/09.html">RPN</a>
*/
public final class CQLRPNGenerator implements Visitor {
/**
* BIB-1 Use attributes resource bundle.
*/
private static final ResourceBundle bib =
ResourceBundle.getBundle("org.xbib.io.iso23950.cql.bib-1");
/**
* Dublin Core Use attributes resource bundle.
*/
private static final ResourceBundle dc =
ResourceBundle.getBundle("org.xbib.io.iso23950.cql.dc");
/**
* Context map.
*/
private final Map<String, ResourceBundle> contexts = new HashMap<String, ResourceBundle>() {
private static final long serialVersionUID = 8199395368653216950L;
{
put("bib", bib);
put("dc", dc);
}
};
private Stack<ASN1Any> result;
private RPNQuery rpnQuery;
public CQLRPNGenerator() {
this.result = new Stack<>();
}
public RPNQuery getQueryResult() {
return rpnQuery;
}
@Override
public void visit(SortedQuery node) {
if (node.getSortSpec() != null) {
node.getSortSpec().accept(this);
}
if (node.getQuery() != null) {
node.getQuery().accept(this);
}
if (!result.isEmpty()) {
this.rpnQuery = new RPNQuery();
rpnQuery.s_rpn = (RPNStructure) result.pop();
// Z39.50 BIB-1: urn:oid:1.2.840.10003.3.1
rpnQuery.s_attributeSet = new AttributeSetId();
rpnQuery.s_attributeSet.value = new ASN1ObjectIdentifier(new int[]{1, 2, 840, 10003, 3, 1});
} else {
throw new SyntaxException("unable to generate RPN from CQL");
}
}
@Override
public void visit(Query node) {
if (node.getPrefixAssignments() != null) {
for (PrefixAssignment assignment : node.getPrefixAssignments()) {
assignment.accept(this);
}
}
if (node.getQuery() != null) {
node.getQuery().accept(this);
}
if (node.getScopedClause() != null) {
node.getScopedClause().accept(this);
}
}
@Override
public void visit(SortSpec node) {
if (node.getSingleSpec() != null) {
node.getSingleSpec().accept(this);
}
if (node.getSortSpec() != null) {
node.getSortSpec().accept(this);
}
}
@Override
public void visit(SingleSpec node) {
if (node.getIndex() != null) {
node.getIndex().accept(this);
}
if (node.getModifierList() != null) {
node.getModifierList().accept(this);
}
}
@Override
public void visit(PrefixAssignment node) {
node.getPrefix().accept(this);
node.getURI().accept(this);
}
@Override
public void visit(ScopedClause node) {
if (node.getScopedClause() != null) {
node.getScopedClause().accept(this);
}
node.getSearchClause().accept(this);
if (node.getBooleanGroup() != null) {
node.getBooleanGroup().accept(this);
RPNStructure rpn = new RPNStructure();
rpn.c_rpnRpnOp = new RPNStructureRpnRpnOp();
rpn.c_rpnRpnOp.s_op = new Operator();
BooleanOperator op = node.getBooleanGroup().getOperator();
switch (op) {
case AND:
rpn.c_rpnRpnOp.s_op.c_and = new ASN1Null();
break;
case OR:
rpn.c_rpnRpnOp.s_op.c_or = new ASN1Null();
break;
case NOT:
rpn.c_rpnRpnOp.s_op.c_and_not = new ASN1Null();
break;
default:
break;
}
rpn.c_rpnRpnOp.s_rpn1 = (RPNStructure) result.pop();
rpn.c_rpnRpnOp.s_rpn2 = (RPNStructure) result.pop();
result.push(rpn);
}
}
@Override
public void visit(BooleanGroup node) {
if (node.getModifierList() != null) {
node.getModifierList().accept(this);
}
}
@Override
public void visit(SearchClause node) {
if (node.getQuery() != null) {
node.getQuery().accept(this);
}
if (node.getTerm() != null) {
node.getTerm().accept(this);
}
if (node.getIndex() != null) {
node.getIndex().accept(this);
}
if (node.getRelation() != null) {
node.getRelation().accept(this);
}
Operand operand = new Operand();
operand.c_attrTerm = new AttributesPlusTerm();
operand.c_attrTerm.sTerm = new org.xbib.io.iso23950.v3.Term();
operand.c_attrTerm.sTerm.c_general = new ASN1OctetString(node.getTerm().getValue());
Stack<AttributeElement> attrs = new Stack<>();
ASN1Any any = !result.isEmpty() && result.peek() instanceof AttributeElement ? result.pop() : null;
while (any != null) {
attrs.push((AttributeElement) any);
any = !result.isEmpty() && result.peek() instanceof AttributeElement ? result.pop() : null;
}
operand.c_attrTerm.sAttributes = new AttributeList();
operand.c_attrTerm.sAttributes.value = attrs.toArray(new AttributeElement[attrs.size()]);
RPNStructure rpn = new RPNStructure();
rpn.c_op = operand;
result.push(rpn);
}
@Override
public void visit(Relation node) {
if (node.getModifierList() != null) {
node.getModifierList().accept(this);
}
int t = 2;
int n = 3;
switch (node.getComparitor()) {
case LESS: // 2=1
n = 1;
break;
case LESS_EQUALS: // 2=2
n = 2;
break;
case EQUALS: // 2=3
n = 3;
break;
case GREATER_EQUALS: // 2=4
n = 4;
break;
case GREATER: // 2=5
n = 5;
break;
case NOT_EQUALS: // 2=6
n = 6;
break;
case ALL: // 4=6
t = 4;
n = 6;
break;
case ANY: // 4=105
t = 4;
n = 104;
break;
default:
break;
}
if (n != 3) {
AttributeElement ae = new AttributeElement();
ae.sAttributeType = new ASN1Integer(t);
ae.attributeValue = new AttributeElementAttributeValue();
ae.attributeValue.cNumeric = new ASN1Integer(n);
result.push(ae);
}
}
@Override
public void visit(Modifier node) {
if (node.getTerm() != null) {
node.getTerm().accept(this);
}
if (node.getName() != null) {
node.getName().accept(this);
}
}
@Override
public void visit(ModifierList node) {
for (Modifier modifier : node.getModifierList()) {
modifier.accept(this);
}
}
@Override
public void visit(Term node) {
int t = 5;
int n = 100;
// check for '*'
String v = node.getValue();
if (v.endsWith("*")) {
if (v.startsWith("*")) {
n = 3;
} else {
n = 1;
}
} else if (v.startsWith("*")) {
n = 2;
}
if (n != 100) {
AttributeElement ae = new AttributeElement();
ae.sAttributeType = new ASN1Integer(t);
ae.attributeValue = new AttributeElementAttributeValue();
ae.attributeValue.cNumeric = new ASN1Integer(n);
result.push(ae);
v = v.replaceAll("\\*", "");
}
ASN1OctetString s = new ASN1OctetString(v);
result.push(s);
}
@Override
public void visit(Identifier node) {
}
@Override
public void visit(SimpleName node) {
ASN1OctetString s = new ASN1OctetString(node.getName());
result.push(s);
}
@Override
public void visit(Index node) {
String context = node.getContext();
if (context == null) {
context = "dc"; // default context
}
int t = 1;
int n = getUseAttr(context, node.getName());
AttributeElement ae = new AttributeElement();
ae.sAttributeType = new ASN1Integer(t);
ae.attributeValue = new AttributeElementAttributeValue();
ae.attributeValue.cNumeric = new ASN1Integer(n);
result.push(ae);
}
private int getUseAttr(String context, String attrName) {
try {
return Integer.parseInt(contexts.get(context).getString(attrName));
} catch (MissingResourceException e) {
throw new SyntaxException("unknown use attribute '" + attrName + "' for context " + context, e);
}
}
}

View file

@ -0,0 +1,37 @@
package org.xbib.io.iso23950.cql;
/**
* Syntax exception.
*/
public class SyntaxException extends RuntimeException {
private static final long serialVersionUID = -3601569690699438132L;
/**
* Creates a new SyntaxException object.
*
* @param msg the message for this syntax exception
*/
public SyntaxException(String msg) {
super(msg);
}
/**
* Creates a new SyntaxException object.
*
* @param t the throwable for this syntax exception
*/
public SyntaxException(Throwable t) {
super(t);
}
/**
* Creates a new SyntaxException object.
*
* @param msg the message for this syntax exception
* @param t the throwable for this syntax exception
*/
public SyntaxException(String msg, Throwable t) {
super(msg, t);
}
}

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.io.iso23950.cql;

View file

@ -0,0 +1,13 @@
package org.xbib.io.iso23950.exceptions;
/**
*
*/
public class MessageSizeTooSmallException extends ZException {
private static final long serialVersionUID = 546319297081247810L;
public MessageSizeTooSmallException(String message, int status, int number) {
super(message, status, number);
}
}

View file

@ -0,0 +1,14 @@
package org.xbib.io.iso23950.exceptions;
/**
*
*/
public class NoRecordsReturnedException extends ZException {
private static final long serialVersionUID = -19157655707502087L;
public NoRecordsReturnedException(String message, int status) {
super(message, status);
}
}

View file

@ -0,0 +1,13 @@
package org.xbib.io.iso23950.exceptions;
/**
*
*/
public class RequestTerminatedByAccessControlException extends ZException {
private static final long serialVersionUID = -54961304899756308L;
public RequestTerminatedByAccessControlException(String message, int status, int number) {
super(message, status, number);
}
}

View file

@ -0,0 +1,13 @@
package org.xbib.io.iso23950.exceptions;
/**
*
*/
public class RequestTerminatedException extends ZException {
private static final long serialVersionUID = 686537068801065383L;
public RequestTerminatedException(String message, int status, int number) {
super(message, status, number);
}
}

View file

@ -0,0 +1,51 @@
package org.xbib.io.iso23950.exceptions;
import java.io.IOException;
/**
*
*/
public class ZException extends IOException {
private static final long serialVersionUID = 8199318316215867038L;
private final int status;
private final int number;
public ZException(String message) {
this(message, -1, -1);
}
public ZException(String message, int status) {
this(message, status, -1);
}
public ZException(String message, int status, int number) {
super(message);
this.status = status;
this.number = number;
}
public ZException(Throwable throwable) {
this(null, throwable);
}
public ZException(String message, Throwable throwable) {
this(message, throwable, -1, -1);
}
public ZException(String message, Throwable throwable, int status, int number) {
super(message, throwable);
this.status = status;
this.number = number;
}
public int getNumber() {
return number;
}
public int getStatus() {
return status;
}
}

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.io.iso23950.exceptions;

View file

@ -0,0 +1,114 @@
package org.xbib.io.iso23950.operations;
import org.xbib.asn1.ASN1BitString;
import org.xbib.asn1.ASN1GeneralString;
import org.xbib.asn1.ASN1Integer;
import org.xbib.io.iso23950.InitListener;
import org.xbib.io.iso23950.ZClient;
import org.xbib.io.iso23950.v3.IdAuthentication;
import org.xbib.io.iso23950.v3.IdAuthenticationIdPass;
import org.xbib.io.iso23950.v3.InitializeRequest;
import org.xbib.io.iso23950.v3.InitializeResponse;
import org.xbib.io.iso23950.v3.InternationalString;
import org.xbib.io.iso23950.v3.Options;
import org.xbib.io.iso23950.v3.PDU;
import org.xbib.io.iso23950.v3.ProtocolVersion;
import java.io.IOException;
/**
* A Z39.50 Init operation.
*/
public class InitOperation {
public boolean execute(ZClient client, Integer preferredMessageSize,
InitListener initListener) throws IOException {
InitializeRequest init = new InitializeRequest();
boolean[] version = new boolean[3];
version[0] = true; // any version, should alwasy be true
version[1] = true; // Z39.50 version 2
version[2] = true; // Z39.50 version 3
init.s_protocolVersion = new ProtocolVersion();
init.s_protocolVersion.value = new ASN1BitString(version);
boolean[] options = new boolean[15];
options[0] = true; // search
options[1] = true; // present
options[2] = true; // delete set
options[3] = false; // resource-report
options[4] = false; // trigger resource control
options[5] = false; // resource control
options[6] = false; // access control
options[7] = true; // scan
options[8] = false; // sort
options[9] = false; // (unused)
options[10] = false; // extended-services
options[11] = false; // level 1 segmentation
options[12] = false; // level 2 segmentation
options[13] = false; // concurrent operations
options[14] = true; // named result sets
init.s_options = new Options();
init.s_options.value = new ASN1BitString(options);
init.s_preferredMessageSize = new ASN1Integer(preferredMessageSize);
init.s_exceptionalRecordSize = new ASN1Integer(preferredMessageSize * 2);
init.s_implementationId = new InternationalString();
init.s_implementationId.value = new ASN1GeneralString("1");
init.s_implementationName = new InternationalString();
init.s_implementationName.value = new ASN1GeneralString("Java ZClient");
init.s_implementationVersion = new InternationalString();
init.s_implementationVersion.value = new ASN1GeneralString("1.00");
if (client.getUser() != null) {
init.s_idAuthentication = new IdAuthentication();
init.s_idAuthentication.c_idPass = new IdAuthenticationIdPass();
init.s_idAuthentication.c_idPass.s_userId = new InternationalString();
init.s_idAuthentication.c_idPass.s_userId.value = new ASN1GeneralString(client.getUser());
if (client.getPass() != null) {
init.s_idAuthentication.c_idPass.s_password = new InternationalString();
init.s_idAuthentication.c_idPass.s_password.value = new ASN1GeneralString(client.getPass());
}
/*if (group != null) {
init.s_idAuthentication.c_idPass.s_groupId = new InternationalString();
init.s_idAuthentication.c_idPass.s_groupId.value = new ASN1GeneralString(group);
}*/
}
PDU pduOut = new PDU();
pduOut.c_initRequest = init;
client.writePDU(pduOut);
PDU pduIn = client.readPDU();
InitializeResponse initResp = pduIn.c_initResponse;
String targetInfo;
if (initResp.s_implementationName != null) {
targetInfo = initResp.s_implementationName.toString();
if (initResp.s_implementationVersion != null) {
targetInfo += " - " + initResp.s_implementationVersion.toString();
}
} else {
targetInfo = "server";
}
int targetVersion = 0;
if (initResp.s_protocolVersion != null) {
for (int n = 0; n < initResp.s_protocolVersion.value.get().length; n++) {
if (initResp.s_protocolVersion.value.get()[n]) {
targetVersion = n + 1;
}
}
if (targetVersion > 0) {
targetInfo += " (Version " + targetVersion + ")";
}
} else {
targetInfo += " (Version unknown)";
}
if (initResp.s_userInformationField != null) {
if (initResp.s_userInformationField.getSingleASN1Type() != null) {
targetInfo += "\n" + initResp.s_userInformationField.getSingleASN1Type().toString();
}
}
if (initResp.s_otherInfo != null) {
targetInfo += "\n" + initResp.s_otherInfo.toString();
}
targetInfo = targetInfo.replaceAll("\"", "");
if (initListener != null) {
initListener.onInit(targetVersion, targetInfo);
}
return !initResp.s_result.get();
}
}

View file

@ -0,0 +1,118 @@
package org.xbib.io.iso23950.operations;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1External;
import org.xbib.asn1.ASN1GeneralString;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1ObjectIdentifier;
import org.xbib.io.iso23950.ErrorRecord;
import org.xbib.io.iso23950.Record;
import org.xbib.io.iso23950.RecordListener;
import org.xbib.io.iso23950.ResponseListener;
import org.xbib.io.iso23950.ZClient;
import org.xbib.io.iso23950.exceptions.MessageSizeTooSmallException;
import org.xbib.io.iso23950.exceptions.NoRecordsReturnedException;
import org.xbib.io.iso23950.exceptions.RequestTerminatedByAccessControlException;
import org.xbib.io.iso23950.exceptions.RequestTerminatedException;
import org.xbib.io.iso23950.exceptions.ZException;
import org.xbib.io.iso23950.v3.ElementSetNames;
import org.xbib.io.iso23950.v3.InternationalString;
import org.xbib.io.iso23950.v3.NamePlusRecord;
import org.xbib.io.iso23950.v3.PDU;
import org.xbib.io.iso23950.v3.PresentRequest;
import org.xbib.io.iso23950.v3.PresentRequestRecordComposition;
import org.xbib.io.iso23950.v3.PresentResponse;
import org.xbib.io.iso23950.v3.PresentStatus;
import org.xbib.io.iso23950.v3.ResultSetId;
import java.io.IOException;
/**
* Present operation for Z39.50.
*/
public class PresentOperation {
public void execute(ZClient client, int offset, int length,
ResponseListener responseListener, RecordListener recordListener) throws IOException {
String resultSetName = client.getResultSetName();
String elementSetName = client.getElementSetName();
String preferredRecordSyntax = client.getPreferredRecordSyntax();
PresentRequest pr = new PresentRequest();
pr.s_resultSetId = new ResultSetId();
pr.s_resultSetId.value = new InternationalString();
pr.s_resultSetId.value.value = new ASN1GeneralString(resultSetName);
pr.s_resultSetStartPoint = new ASN1Integer(offset);
pr.s_numberOfRecordsRequested = new ASN1Integer(length);
pr.s_recordComposition = new PresentRequestRecordComposition();
pr.s_recordComposition.c_simple = new ElementSetNames();
pr.s_recordComposition.c_simple.cGenericElementSetName = new InternationalString();
pr.s_recordComposition.c_simple.cGenericElementSetName.value = new ASN1GeneralString(elementSetName);
pr.s_preferredRecordSyntax = new ASN1ObjectIdentifier(makeOID(preferredRecordSyntax));
PDU pdu = new PDU();
pdu.c_presentRequest = pr;
long millis = System.currentTimeMillis();
client.writePDU(pdu);
pdu = client.readPDU();
PresentResponse response = pdu.c_presentResponse;
int nReturned = response.s_numberOfRecordsReturned != null ? response.s_numberOfRecordsReturned.get() : 0;
int status = response.s_presentStatus.value != null ? response.s_presentStatus.value.get() : 0;
if (responseListener != null) {
responseListener.onResponse(status, nReturned, System.currentTimeMillis() - millis);
}
if (status == PresentStatus.E_success) {
for (int n = 0; n < nReturned; n++) {
NamePlusRecord nr = response.s_records.c_responseRecords[n];
try {
if (nr.s_record.c_retrievalRecord != null) {
ASN1External asn1External = new ASN1External(nr.s_record.c_retrievalRecord.berEncode(), true);
Record record = new Record(offset + n, asn1External.getcOctetAligned().getBytes());
if (recordListener != null) {
recordListener.onRecord(record);
}
} else if (nr.s_record.c_surrogateDiagnostic != null) {
ASN1External asn1External =
new ASN1External(nr.s_record.c_surrogateDiagnostic.cDefaultFormat.berEncode(), true);
ErrorRecord record = new ErrorRecord(offset + n, asn1External.getcOctetAligned().getBytes());
if (recordListener != null) {
recordListener.onRecord(record);
}
}
} catch (ASN1Exception e) {
throw new IOException("Present error: " + e.getMessage());
}
}
} else {
throw createZExceptionFrom(status, nReturned, response);
}
}
private int[] makeOID(String str) throws NumberFormatException {
String[] s = str.split("\\.");
int[] a = new int[s.length];
for (int i = 0; i < a.length; i++) {
a[i] = Integer.parseInt(s[i]);
}
return a;
}
private ZException createZExceptionFrom(int status, int nReturned, PresentResponse response) {
String message;
switch (status) {
case 1:
message = "Some records were not returned (request was terminated by access control)";
return new NoRecordsReturnedException(message, status);
case 2:
message = "Some records were not returned (message size is too small)";
return new MessageSizeTooSmallException(message, status, nReturned);
case 3:
message = "Some records were not returned (request was terminated by control, at origin request)";
return new RequestTerminatedByAccessControlException(message, status, nReturned);
case 4:
message = "Some records were not returned (request was terminated by control, by the target)";
return new RequestTerminatedException(message, status, nReturned);
case 5:
return new NoRecordsReturnedException(response.toString(), status);
}
return new ZException(response.toString(), status, nReturned);
}
}

View file

@ -0,0 +1,121 @@
package org.xbib.io.iso23950.operations;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1Boolean;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1GeneralString;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.io.iso23950.ZClient;
import org.xbib.io.iso23950.v3.DatabaseName;
import org.xbib.io.iso23950.v3.InternationalString;
import org.xbib.io.iso23950.v3.OtherInformation1;
import org.xbib.io.iso23950.v3.PDU;
import org.xbib.io.iso23950.v3.PresentStatus;
import org.xbib.io.iso23950.v3.Query;
import org.xbib.io.iso23950.v3.RPNQuery;
import org.xbib.io.iso23950.v3.SearchRequest;
import org.xbib.io.iso23950.v3.SearchResponse;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Base class for Z39.50 Search operation.
*/
public class SearchOperation {
private int count = -1;
private boolean status = false;
private Map<ASN1Any, Integer> results = new HashMap<>();
public boolean execute(ZClient client, RPNQuery rpn) throws IOException {
try {
SearchRequest search = new SearchRequest();
search.s_query = new Query();
search.s_query.c_type_1 = rpn;
search.s_smallSetUpperBound = new ASN1Integer(0);
search.s_largeSetLowerBound = new ASN1Integer(1);
search.s_mediumSetPresentNumber = new ASN1Integer(0);
search.s_replaceIndicator = new ASN1Boolean(true);
search.s_resultSetName = new InternationalString();
search.s_resultSetName.value = new ASN1GeneralString(client.getResultSetName());
List<String> databases = client.getDatabases();
DatabaseName dbs[] = new DatabaseName[databases.size()];
for (int n = 0; n < databases.size(); n++) {
dbs[n] = new DatabaseName();
dbs[n].value = new InternationalString();
dbs[n].value.value = new ASN1GeneralString(databases.get(n));
}
search.s_databaseNames = dbs;
PDU pduRequest = new PDU();
pduRequest.c_searchRequest = search;
client.writePDU(pduRequest);
PDU pduResponse = client.readPDU();
SearchResponse response = pduResponse.c_searchResponse;
count = response.s_resultCount.get();
ASN1Boolean b = response.s_searchStatus;
status = b != null && b.get();
if (!status) {
String message = "no message";
if (response.s_records != null && response.s_records.c_nonSurrogateDiagnostic != null) {
try {
message = "ASN error, non-surrogate diagnostics: " +
response.s_records.c_nonSurrogateDiagnostic.berEncode();
} catch (ASN1Exception e) {
//
}
}
throw new IOException(client.getHost() + ": " + message);
}
PresentStatus presentStatus = response.s_presentStatus;
if (presentStatus != null && presentStatus.value != null && presentStatus.value.get() == 5) {
throw new IOException("present status is failure");
}
if (response.s_additionalSearchInfo != null && response.s_additionalSearchInfo.value[0] != null) {
OtherInformation1 info = response.s_additionalSearchInfo.value[0];
ASN1Sequence targetSeq = (ASN1Sequence) info.s_information.c_externallyDefinedInfo.getSingleASN1Type();
ASN1Any[] targets = targetSeq.get();
DatabaseName dbName;
for (int i = 0; i < targets.length; i++) {
ASN1Sequence target = (ASN1Sequence) targets[i];
try {
ASN1Any[] details = target.get();
dbName = new DatabaseName(details[0].berEncode(), false);
if (!dbName.value.value.get().equalsIgnoreCase(databases.get(i))) {
String message = "database name listed in additional search info " +
"doesn't match database name in names set.";
throw new IOException(client.getHost() + ": " + message);
}
ASN1Integer res = (ASN1Integer) details[1];
results.put(target, res.get());
} catch (ASN1Exception ex) {
// non-fatal String message = "Error in accessing additional search info.";
results.put(target, -1);
}
}
}
} catch (SocketTimeoutException e) {
throw new IOException(client.getHost() + ": timeout", e);
}
return status;
}
public int getCount() {
return count;
}
public boolean isSuccess() {
return status;
}
public Map<ASN1Any, Integer> getResults() {
return results;
}
}

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.io.iso23950.operations;

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.io.iso23950;

View file

@ -0,0 +1,47 @@
package org.xbib.io.iso23950.pqf;
/**
* PQF abstract syntax tree.
*/
public class AttrStr extends Node {
private Integer left;
private Integer right;
private String rightStr;
public AttrStr(Integer left, Integer right) {
this.left = left;
this.right = right;
}
public AttrStr(Integer left, String right) {
this.left = left;
this.rightStr = right;
}
@Override
public void accept(Visitor visitor) {
if (rightStr != null) {
visitor.visit(rightStr);
}
if (right != null) {
visitor.visit(right);
}
if (left != null) {
visitor.visit(left);
}
visitor.visit(this);
}
public Integer getLeft() {
return left;
}
public Integer getRight() {
return right;
}
public String getRightStr() {
return rightStr;
}
}

View file

@ -0,0 +1,30 @@
package org.xbib.io.iso23950.pqf;
/**
* PQF abstract syntax tree.
*/
public class Expression extends Node {
private String op;
private Query q1;
private Query q2;
public Expression(String op, Query q1, Query q2) {
this.op = op;
this.q1 = q1;
this.q2 = q2;
}
@Override
public void accept(Visitor visitor) {
q2.accept(visitor);
q1.accept(visitor);
visitor.visit(this);
}
public String getOperator() {
return op;
}
}

View file

@ -0,0 +1,15 @@
package org.xbib.io.iso23950.pqf;
/**
* PQF abstract syntax tree.
*/
public abstract class Node {
/**
* Try to accept this node by a visitor.
*
* @param v the visitor
*/
public abstract void accept(Visitor v);
}

View file

@ -0,0 +1,34 @@
package org.xbib.io.iso23950.pqf;
/**
* PQF abstract syntax tree.
*/
public class PQF extends Node {
private final String attrset;
private final Query query;
public PQF(String attrset, Query query) {
this.attrset = attrset;
this.query = query;
}
public PQF(Query query) {
this.attrset = null; // default
this.query = query;
}
public void accept(Visitor visitor) {
query.accept(visitor);
visitor.visit(this);
}
public String getAttrSet() {
return attrset;
}
@Override
public String toString() {
return "[PQF: attrset=" + attrset + " query=" + query + "]";
}
}

View file

@ -0,0 +1,122 @@
package org.xbib.io.iso23950.pqf;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1Null;
import org.xbib.asn1.ASN1ObjectIdentifier;
import org.xbib.asn1.ASN1OctetString;
import org.xbib.io.iso23950.v3.AttributeElement;
import org.xbib.io.iso23950.v3.AttributeElementAttributeValue;
import org.xbib.io.iso23950.v3.AttributeList;
import org.xbib.io.iso23950.v3.AttributeSetId;
import org.xbib.io.iso23950.v3.AttributesPlusTerm;
import org.xbib.io.iso23950.v3.Operand;
import org.xbib.io.iso23950.v3.Operator;
import org.xbib.io.iso23950.v3.RPNQuery;
import org.xbib.io.iso23950.v3.RPNStructure;
import org.xbib.io.iso23950.v3.RPNStructureRpnRpnOp;
import java.util.Stack;
/**
* PQF abstract syntax tree.
*/
public class PQFRPNGenerator implements Visitor {
private Stack<ASN1Any> result;
private RPNQuery rpnQuery;
public PQFRPNGenerator() {
this.result = new Stack<>();
}
public RPNQuery getResult() {
return rpnQuery;
}
@Override
public void visit(PQF pqf) {
if (!result.isEmpty()) {
this.rpnQuery = new RPNQuery();
rpnQuery.s_rpn = (RPNStructure) result.pop();
if (pqf.getAttrSet() == null) {
// Z39.50 BIB-1: urn:oid:1.2.840.10003.3.1
rpnQuery.s_attributeSet = new AttributeSetId();
rpnQuery.s_attributeSet.value = new ASN1ObjectIdentifier(new int[]{1, 2, 840, 10003, 3, 1});
}
} else {
throw new SyntaxException("no valid PQF found");
}
}
@Override
public void visit(Query query) {
Operand operand = new Operand();
operand.c_attrTerm = new AttributesPlusTerm();
operand.c_attrTerm.sTerm = new org.xbib.io.iso23950.v3.Term();
operand.c_attrTerm.sTerm.c_general = new ASN1OctetString(query.getTerm().getValue());
Stack<AttributeElement> attrs = new Stack<>();
ASN1Any any = !result.isEmpty() && result.peek() instanceof AttributeElement ? result.pop() : null;
while (any != null) {
attrs.push((AttributeElement) any);
any = !result.isEmpty() && result.peek() instanceof AttributeElement ? result.pop() : null;
}
operand.c_attrTerm.sAttributes = new AttributeList();
operand.c_attrTerm.sAttributes.value = attrs.toArray(new AttributeElement[attrs.size()]);
RPNStructure rpn = new RPNStructure();
rpn.c_op = operand;
if (attrs.size() > 0) {
result.push(rpn);
}
}
@Override
public void visit(Expression expr) {
String op = expr.getOperator();
RPNStructure rpn = new RPNStructure();
rpn.c_rpnRpnOp = new RPNStructureRpnRpnOp();
rpn.c_rpnRpnOp.s_op = new Operator();
if ("@and".equals(op)) {
rpn.c_rpnRpnOp.s_op.c_and = new ASN1Null();
}
if ("@or".equals(op)) {
rpn.c_rpnRpnOp.s_op.c_or = new ASN1Null();
}
if ("@not".equals(op)) {
rpn.c_rpnRpnOp.s_op.c_and_not = new ASN1Null();
}
rpn.c_rpnRpnOp.s_rpn1 = (RPNStructure) result.pop();
rpn.c_rpnRpnOp.s_rpn2 = (RPNStructure) result.pop();
result.push(rpn);
}
@Override
public void visit(AttrStr attrspec) {
AttributeElement ae = new AttributeElement();
ae.sAttributeType = (ASN1Integer) result.pop();
ae.attributeValue = new AttributeElementAttributeValue();
ae.attributeValue.cNumeric = (ASN1Integer) result.pop();
result.push(ae);
}
@Override
public void visit(Term term) {
result.push(new ASN1OctetString(term.getValue()));
}
@Override
public void visit(Setname name) {
result.push(new ASN1OctetString(name.getValue()));
}
@Override
public void visit(Integer i) {
result.push(new ASN1Integer(i));
}
@Override
public void visit(String str) {
result.push(new ASN1OctetString(str));
}
}

View file

@ -0,0 +1,97 @@
package org.xbib.io.iso23950.pqf;
import java.util.LinkedList;
/**
* PQF abstract syntax tree.
*/
public class Query extends Node {
private String attrschema;
private LinkedList<AttrStr> attrspec = new LinkedList<>();
private Query querystruct;
private Setname setname;
private Term term;
private Expression expr;
private PQF pqf;
// ATTR CHARSTRING1 attrstr querystruct
public Query(String attrschema, AttrStr attrspec, Query querystruct) {
this.attrschema = attrschema;
this.attrspec.add(attrspec);
this.querystruct = querystruct;
this.term = querystruct.getTerm();
this.attrspec.addAll(querystruct.getAttrSpec());
}
// ATTR attrspec querystruct
public Query(AttrStr attrspec, Query querystruct) {
this.attrspec.add(attrspec);
this.querystruct = querystruct;
this.term = querystruct.getTerm();
this.attrspec.addAll(querystruct.getAttrSpec());
}
// TERM TERMTYPE pqf
public Query(PQF pqf) {
this.pqf = pqf;
}
// simple
public Query(Term term) {
this.term = term;
}
// complex
public Query(Expression expr) {
this.expr = expr;
}
public Query(Setname setname) {
this.setname = setname;
}
public void accept(Visitor visitor) {
if (term != null) {
term.accept(visitor);
}
if (setname != null) {
setname.accept(visitor);
}
if (expr != null) {
expr.accept(visitor);
}
if (querystruct != null) {
querystruct.accept(visitor);
}
for (AttrStr attr : attrspec) {
attr.accept(visitor);
}
if (pqf != null) {
pqf.accept(visitor);
}
visitor.visit(this);
}
public String getSchema() {
return attrschema;
}
public Setname getSetname() {
return setname;
}
public Term getTerm() {
return term;
}
public LinkedList<AttrStr> getAttrSpec() {
return attrspec;
}
@Override
public String toString() {
return "[Query: term=" + term + " attrschema=" + attrschema + " setname=" + setname +
" querystruct=" + querystruct + "]";
}
}

View file

@ -0,0 +1,26 @@
package org.xbib.io.iso23950.pqf;
/**
*
*/
public class Setname extends Node {
private final String value;
public Setname(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String toString() {
return value;
}
}

View file

@ -0,0 +1,18 @@
package org.xbib.io.iso23950.pqf;
/**
* Syntax exception.
*/
public class SyntaxException extends RuntimeException {
private static final long serialVersionUID = -962913398056374183L;
/**
* Creates a new SyntaxException object.
*
* @param msg the message for this syntax exception
*/
public SyntaxException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,26 @@
package org.xbib.io.iso23950.pqf;
/**
*
*/
public class Term extends Node {
private final String value;
public Term(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String toString() {
return value;
}
}

View file

@ -0,0 +1,39 @@
package org.xbib.io.iso23950.pqf;
/**
* PQF abstract syntax tree visitor.
*/
public interface Visitor {
/**
* Visit PQF.
*
* @param pqf the tree to visit.
*/
void visit(PQF pqf);
/**
* Visit an query.
*
* @param query the query to visit.
*/
void visit(Query query);
/**
* Visit an expression.
*
* @param expression the expression to visit.
*/
void visit(Expression expression);
void visit(AttrStr attrspec);
void visit(Term term);
void visit(Setname name);
void visit(String str);
void visit(Integer i);
}

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.io.iso23950.pqf;

View file

@ -0,0 +1,163 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AccessControlRequest</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AccessControlRequest ::=
* SEQUENCE {
* referenceId ReferenceId OPTIONAL
* securityChallenge AccessControlRequest_securityChallenge
* otherInfo OtherInformation OPTIONAL
* }
* </pre>
*/
public final class AccessControlRequest extends ASN1Any {
public ReferenceId sReferenceId; // optional
public AccessControlRequestSecurityChallenge sSecurityChallenge;
public OtherInformation sOtherInfo; // optional
/**
* Constructor for a AccessControlRequest from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AccessControlRequest(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
@Override
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("AccessControlRequest: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
if (numParts <= part) {
throw new ASN1Exception("AccessControlRequest: incomplete");
}
p = berConstructed.elementAt(part);
try {
sReferenceId = new ReferenceId(p, true);
part++;
} catch (ASN1Exception e) {
sReferenceId = null; // no, not present
}
if (numParts <= part) {
throw new ASN1Exception("AccessControlRequest: incomplete");
}
p = berConstructed.elementAt(part);
sSecurityChallenge = new AccessControlRequestSecurityChallenge(p, true);
part++;
sOtherInfo = null;
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
try {
sOtherInfo = new OtherInformation(p, true);
part++;
} catch (ASN1Exception e) {
sOtherInfo = null;
}
if (part < numParts) {
throw new ASN1Exception("AccessControlRequest: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the AccessControlRequest.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of AccessControlRequest, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 1;
if (sReferenceId != null) {
numFields++;
}
if (sOtherInfo != null) {
numFields++;
}
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
if (sReferenceId != null) {
fields[x++] = sReferenceId.berEncode();
}
fields[x++] = sSecurityChallenge.berEncode();
if (sOtherInfo != null) {
fields[x] = sOtherInfo.berEncode();
}
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the AccessControlRequest.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
int outputted = 0;
if (sReferenceId != null) {
str.append("referenceId ");
str.append(sReferenceId);
outputted++;
}
if (0 < outputted) {
str.append(", ");
}
str.append("securityChallenge ");
str.append(sSecurityChallenge);
outputted++;
if (sOtherInfo != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("otherInfo ");
str.append(sOtherInfo);
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,131 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1External;
import org.xbib.asn1.ASN1OctetString;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AccessControlRequest_securityChallenge</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AccessControlRequest_securityChallenge ::=
* CHOICE {
* simpleForm [37] IMPLICIT OCTET STRING
* externallyDefined [0] EXPLICIT EXTERNAL
* }
* </pre>
*/
public final class AccessControlRequestSecurityChallenge extends ASN1Any {
public ASN1OctetString cSimpleForm;
public ASN1External cExternallyDefined;
/**
* Constructor for a AccessControlRequest_securityChallenge from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AccessControlRequestSecurityChallenge(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
@Override
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed tagwrapper;
cSimpleForm = null;
cExternallyDefined = null;
if (ber.tagGet() == 37 &&
ber.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
cSimpleForm = new ASN1OctetString(ber, false);
return;
}
if (ber.tagGet() == 0 &&
ber.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
try {
tagwrapper = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("AccessControlRequest_securityChallenge: bad BER form\n");
}
if (tagwrapper.numberComponents() != 1) {
throw new ASN1EncodingException("AccessControlRequest_securityChallenge: bad BER form\n");
}
cExternallyDefined = new ASN1External(tagwrapper.elementAt(0), true);
return;
}
throw new ASN1Exception("AccessControlRequest_securityChallenge: bad BER encoding: choice not matched");
}
/**
* Returns a BER encoding of AccessControlRequest_securityChallenge.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
BEREncoding chosen = null;
BEREncoding enc[];
if (cSimpleForm != null) {
chosen = cSimpleForm.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 37);
}
if (cExternallyDefined != null) {
if (chosen != null) {
throw new ASN1Exception("CHOICE multiply set");
}
enc = new BEREncoding[1];
enc[0] = cExternallyDefined.berEncode();
chosen = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 0, enc);
}
if (chosen == null) {
throw new ASN1Exception("CHOICE not set");
}
return chosen;
}
@Override
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
throw new ASN1EncodingException("AccessControlRequest_securityChallenge: cannot implicitly tag");
}
/**
* Returns a new String object containing a text representing
* of the AccessControlRequest_securityChallenge.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder("{");
boolean found = false;
if (cSimpleForm != null) {
found = true;
str.append("simpleForm ");
str.append(cSimpleForm);
}
if (cExternallyDefined != null) {
if (found) {
str.append("<ERROR: multiple CHOICE: externallyDefined> ");
}
str.append("externallyDefined ");
str.append(cExternallyDefined);
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,215 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AccessControlResponse</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AccessControlResponse ::=
* SEQUENCE {
* referenceId ReferenceId OPTIONAL
* securityChallengeResponse AccessControlResponse_securityChallengeResponse OPTIONAL
* diagnostic [223] EXPLICIT DiagRec OPTIONAL
* otherInfo OtherInformation OPTIONAL
* }
* </pre>
*/
public final class AccessControlResponse extends ASN1Any {
public ReferenceId referenceId; // optional
public AccessControlResponseSecurityChallengeResponse securityChallengeResponse; // optional
public DiagRec diagRec; // optional
public OtherInformation otherInformation; // optional
/**
* Constructor for a AccessControlResponse from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AccessControlResponse(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
@Override
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("AccessControlResponse: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
BERConstructed tagged;
referenceId = null;
securityChallengeResponse = null;
diagRec = null;
otherInformation = null;
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
try {
referenceId = new ReferenceId(p, true);
part++;
} catch (ASN1Exception e) {
referenceId = null;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
try {
securityChallengeResponse = new AccessControlResponseSecurityChallengeResponse(p, true);
part++;
} catch (ASN1Exception e) {
securityChallengeResponse = null;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 223 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
try {
tagged = (BERConstructed) p;
} catch (ClassCastException e) {
throw new ASN1EncodingException("AccessControlResponse: bad BER encoding: s_diagnostic tag bad\n");
}
if (tagged.numberComponents() != 1) {
throw new ASN1EncodingException("AccessControlResponse: bad BER encoding: s_diagnostic tag bad\n");
}
diagRec = new DiagRec(tagged.elementAt(0), true);
part++;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
try {
otherInformation = new OtherInformation(p, true);
part++;
} catch (ASN1Exception e) {
otherInformation = null;
}
if (part < numParts) {
throw new ASN1Exception("AccessControlResponse: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the AccessControlResponse.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
@Override
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of AccessControlResponse, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
@Override public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 0; // number of mandatories
if (referenceId != null) {
numFields++;
}
if (securityChallengeResponse != null) {
numFields++;
}
if (diagRec != null) {
numFields++;
}
if (otherInformation != null) {
numFields++;
}
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
BEREncoding enc[];
if (referenceId != null) {
fields[x++] = referenceId.berEncode();
}
if (securityChallengeResponse != null) {
fields[x++] = securityChallengeResponse.berEncode();
}
if (diagRec != null) {
enc = new BEREncoding[1];
enc[0] = diagRec.berEncode();
fields[x++] = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 223, enc);
}
if (otherInformation != null) {
fields[x] = otherInformation.berEncode();
}
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the AccessControlResponse.
*/
@Override
public String toString() {
StringBuilder str = new StringBuilder("{");
int outputted = 0;
if (referenceId != null) {
str.append("referenceId ");
str.append(referenceId);
outputted++;
}
if (securityChallengeResponse != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("securityChallengeResponse ");
str.append(securityChallengeResponse);
outputted++;
}
if (diagRec != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("diagnostic ");
str.append(diagRec);
outputted++;
}
if (otherInformation != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("otherInfo ");
str.append(otherInformation);
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,130 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1External;
import org.xbib.asn1.ASN1OctetString;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AccessControlResponse_securityChallengeResponse</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AccessControlResponse_securityChallengeResponse ::=
* CHOICE {
* simpleForm [38] IMPLICIT OCTET STRING
* externallyDefined [0] EXPLICIT EXTERNAL
* }
* </pre>
*/
public final class AccessControlResponseSecurityChallengeResponse extends ASN1Any {
public ASN1OctetString cSimpleForm;
public ASN1External cExternallyDefined;
/**
* Constructor for a AccessControlResponse_securityChallengeResponse from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AccessControlResponseSecurityChallengeResponse(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed tagwrapper;
cSimpleForm = null;
cExternallyDefined = null;
if (ber.tagGet() == 38 &&
ber.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
cSimpleForm = new ASN1OctetString(ber, false);
return;
}
if (ber.tagGet() == 0 &&
ber.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
try {
tagwrapper = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("AccessControlResponse_securityChallengeResponse: bad BER form");
}
if (tagwrapper.numberComponents() != 1) {
throw new ASN1EncodingException("AccessControlResponse_securityChallengeResponse: bad BER form");
}
cExternallyDefined = new ASN1External(tagwrapper.elementAt(0), true);
return;
}
throw new ASN1Exception("AccessControlResponse_securityChallengeResponse: bad BER encoding: choice not matched");
}
/**
* Returns a BER encoding of AccessControlResponse_securityChallengeResponse.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
BEREncoding chosen = null;
BEREncoding enc[];
if (cSimpleForm != null) {
chosen = cSimpleForm.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 38);
}
if (cExternallyDefined != null) {
if (chosen != null) {
throw new ASN1Exception("CHOICE multiply set");
}
enc = new BEREncoding[1];
enc[0] = cExternallyDefined.berEncode();
chosen = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 0, enc);
}
if (chosen == null) {
throw new ASN1Exception("CHOICE not set");
}
return chosen;
}
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
throw new ASN1EncodingException("AccessControlResponse_securityChallengeResponse: cannot implicitly tag");
}
/**
* Returns a new String object containing a text representing
* of the AccessControlResponse_securityChallengeResponse.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
boolean found = false;
if (cSimpleForm != null) {
found = true;
str.append("simpleForm ");
str.append(cSimpleForm);
}
if (cExternallyDefined != null) {
if (found) {
str.append("<ERROR: multiple CHOICE: externallyDefined> ");
}
str.append("externallyDefined ");
str.append(cExternallyDefined);
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,162 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AttributeElement</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AttributeElement ::=
* SEQUENCE {
* attributeSet [1] IMPLICIT AttributeSetId OPTIONAL
* attributeType [120] IMPLICIT INTEGER
* attributeValue AttributeElement_attributeValue
* }
* </pre>
*/
public final class AttributeElement extends ASN1Any {
public AttributeSetId attributeSetId; // optional
public ASN1Integer sAttributeType;
public AttributeElementAttributeValue attributeValue;
/**
* Default constructor for a AttributeElement.
*/
public AttributeElement() {
}
/**
* Constructor for a AttributeElement from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AttributeElement(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("AttributeElement: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
if (numParts <= part) {
throw new ASN1Exception("AttributeElement: incomplete");
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 1 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
attributeSetId = new AttributeSetId(p, false);
part++;
}
if (numParts <= part) {
throw new ASN1Exception("AttributeElement: incomplete");
}
p = berConstructed.elementAt(part);
if (p.tagGet() != 120 ||
p.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("AttributeElement: bad tag in s_attributeType\n");
}
sAttributeType = new ASN1Integer(p, false);
part++;
if (numParts <= part) {
throw new ASN1Exception("AttributeElement: incomplete");
}
p = berConstructed.elementAt(part);
attributeValue = new AttributeElementAttributeValue(p, true);
part++;
if (part < numParts) {
throw new ASN1Exception("AttributeElement: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the AttributeElement.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of AttributeElement, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
* @see org.xbib.asn1.BEREncoding#UNIVERSAL_TAG
* @see org.xbib.asn1.BEREncoding#APPLICATION_TAG
* @see org.xbib.asn1.BEREncoding#CONTEXT_SPECIFIC_TAG
* @see org.xbib.asn1.BEREncoding#PRIVATE_TAG
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 2;
if (attributeSetId != null) {
numFields++;
}
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
if (attributeSetId != null) {
fields[x++] = attributeSetId.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 1);
}
fields[x++] = sAttributeType.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 120);
fields[x] = attributeValue.berEncode();
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the AttributeElement.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
int outputted = 0;
if (attributeSetId != null) {
str.append("attributeSet ");
str.append(attributeSetId);
outputted++;
}
if (0 < outputted) {
str.append(", ");
}
str.append("attributeType ");
str.append(sAttributeType);
outputted++;
if (0 < outputted) {
str.append(", ");
}
str.append("attributeValue ");
str.append(attributeValue);
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,119 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AttributeElement_attributeValue</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AttributeElement_attributeValue ::=
* CHOICE {
* numeric [121] IMPLICIT INTEGER
* complex [224] IMPLICIT AttributeElement_attributeValue_complex
* }
* </pre>
*/
public final class AttributeElementAttributeValue extends ASN1Any {
public ASN1Integer cNumeric;
public AttributeElementAttributeValueComplex attributeValueComplex;
/**
* Default constructor for a AttributeElement_attributeValue.
*/
public AttributeElementAttributeValue() {
}
/**
* Constructor for a AttributeElement_attributeValue from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AttributeElementAttributeValue(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
cNumeric = null;
attributeValueComplex = null;
if (ber.tagGet() == 121 &&
ber.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
cNumeric = new ASN1Integer(ber, false);
return;
}
if (ber.tagGet() == 224 &&
ber.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
attributeValueComplex = new AttributeElementAttributeValueComplex(ber, false);
return;
}
throw new ASN1Exception("AttributeElement_attributeValue: bad BER encoding: choice not matched");
}
/**
* Returns a BER encoding of AttributeElement_attributeValue.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
BEREncoding chosen = null;
if (cNumeric != null) {
chosen = cNumeric.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 121);
}
if (attributeValueComplex != null) {
if (chosen != null) {
throw new ASN1Exception("CHOICE multiply set");
}
chosen = attributeValueComplex.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 224);
}
if (chosen == null) {
throw new ASN1Exception("CHOICE not set");
}
return chosen;
}
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
throw new ASN1EncodingException("AttributeElement_attributeValue: cannot implicitly tag");
}
/**
* Returns a new String object containing a text representing
* of the AttributeElement_attributeValue.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
boolean found = false;
if (cNumeric != null) {
found = true;
str.append("numeric ");
str.append(cNumeric);
}
if (attributeValueComplex != null) {
if (found) {
str.append("<ERROR: multiple CHOICE: complex> ");
}
str.append("complex ");
str.append(attributeValueComplex);
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,182 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AttributeElement_attributeValue_complex</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AttributeElement_attributeValue_complex ::=
* SEQUENCE {
* list [1] IMPLICIT SEQUENCE OF StringOrNumeric
* semanticAction [2] IMPLICIT SEQUENCE OF INTEGER OPTIONAL
* }
* </pre>
*/
public final class AttributeElementAttributeValueComplex extends ASN1Any {
public StringOrNumeric[] sList;
public ASN1Integer[] sSemanticAction; // optional
/**
* Constructor for a AttributeElement_attributeValue_complex from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AttributeElementAttributeValueComplex(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("AttributeElement_attributeValue_complex: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
if (numParts <= part) {
throw new ASN1Exception("AttributeElement_attributeValue_complex: incomplete");
}
p = berConstructed.elementAt(part);
if (p.tagGet() != 1 ||
p.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("AttributeElement_attributeValue_complex: bad tag in s_list\n");
}
try {
BERConstructed cons = (BERConstructed) p;
int parts = cons.numberComponents();
sList = new StringOrNumeric[parts];
int n;
for (n = 0; n < parts; n++) {
sList[n] = new StringOrNumeric(cons.elementAt(n), true);
}
} catch (ClassCastException e) {
throw new ASN1EncodingException("Bad BER");
}
part++;
sSemanticAction = null;
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 2 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
try {
BERConstructed cons = (BERConstructed) p;
int parts = cons.numberComponents();
sSemanticAction = new ASN1Integer[parts];
int n;
for (n = 0; n < parts; n++) {
sSemanticAction[n] = new ASN1Integer(cons.elementAt(n), true);
}
} catch (ClassCastException e) {
throw new ASN1EncodingException("Bad BER");
}
part++;
}
if (part < numParts) {
throw new ASN1Exception("AttributeElement_attributeValue_complex: bad BER: extra data " +
part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the AttributeElement_attributeValue_complex.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of AttributeElement_attributeValue_complex, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 1;
if (sSemanticAction != null) {
numFields++;
}
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
BEREncoding f2[];
int p;
f2 = new BEREncoding[sList.length];
for (p = 0; p < sList.length; p++) {
f2[p] = sList[p].berEncode();
}
fields[x++] = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 1, f2);
if (sSemanticAction != null) {
f2 = new BEREncoding[sSemanticAction.length];
for (p = 0; p < sSemanticAction.length; p++) {
f2[p] = sSemanticAction[p].berEncode();
}
fields[x] = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 2, f2);
}
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the AttributeElement_attributeValue_complex.
*/
public String toString() {
int p;
StringBuilder str = new StringBuilder("{");
int outputted = 0;
str.append("list ");
str.append("{");
for (p = 0; p < sList.length; p++) {
if (p != 0) {
str.append(", ");
}
str.append(sList[p]);
}
str.append("}");
outputted++;
if (sSemanticAction != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("semanticAction ");
str.append("{");
for (p = 0; p < sSemanticAction.length; p++) {
if (p != 0) {
str.append(", ");
}
str.append(sSemanticAction[p]);
}
str.append("}");
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,110 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AttributeList</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AttributeList ::=
* [44] IMPLICIT SEQUENCE OF AttributeElement
* </pre>
*/
public final class AttributeList extends ASN1Any {
public AttributeElement[] value;
/**
* Default constructor for a AttributeList.
*/
public AttributeList() {
}
/**
* Constructor for a AttributeList from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AttributeList(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
if (checkTag) {
if (ber.tagGet() != 44 ||
ber.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("AttributeList: bad BER: tag=" + ber.tagGet() + " expected 44\n");
}
}
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("AttributeList: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
value = new AttributeElement[numParts];
int p;
for (p = 0; p < numParts; p++) {
value[p] = new AttributeElement(berConstructed.elementAt(p), true);
}
}
/**
* Returns a BER encoding of the AttributeList.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 44);
}
/**
* Returns a BER encoding of AttributeList, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
BEREncoding fields[] = new BERConstructed[value.length];
int p;
for (p = 0; p < value.length; p++) {
fields[p] = value[p].berEncode();
}
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the AttributeList.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
int p;
for (p = 0; p < value.length; p++) {
str.append(value[p]);
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,82 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1ObjectIdentifier;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AttributeSetId</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AttributeSetId ::=
* OBJECT IDENTIFIER
* </pre>
*/
public final class AttributeSetId extends ASN1Any {
public ASN1ObjectIdentifier value;
/**
* Default constructor for a AttributeSetId.
*/
public AttributeSetId() {
}
/**
* Constructor for a AttributeSetId from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AttributeSetId(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
value = new ASN1ObjectIdentifier(ber, checkTag);
}
/**
* Returns a BER encoding of the AttributeSetId.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return value.berEncode();
}
/**
* Returns a BER encoding of AttributeSetId, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
return value.berEncode(tagType, tag);
}
/**
* Returns a new String object containing a text representing
* of the AttributeSetId.
*/
public String toString() {
return value.toString();
}
}

View file

@ -0,0 +1,136 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>AttributesPlusTerm</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* AttributesPlusTerm ::=
* [102] IMPLICIT SEQUENCE {
* attributes AttributeList
* term Term
* }
* </pre>
*/
public final class AttributesPlusTerm extends ASN1Any {
public AttributeList sAttributes;
public Term sTerm;
/**
* Default constructor for a AttributesPlusTerm.
*/
public AttributesPlusTerm() {
}
/**
* Constructor for a AttributesPlusTerm from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public AttributesPlusTerm(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
if (checkTag) {
if (ber.tagGet() != 102 ||
ber.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException
("AttributesPlusTerm: bad BER: tag=" + ber.tagGet() + " expected 102\n");
}
}
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException
("AttributesPlusTerm: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
if (numParts <= part) {
throw new ASN1Exception("AttributesPlusTerm: incomplete");
}
p = berConstructed.elementAt(part);
sAttributes = new AttributeList(p, true);
part++;
if (numParts <= part) {
throw new ASN1Exception("AttributesPlusTerm: incomplete");
}
p = berConstructed.elementAt(part);
sTerm = new Term(p, true);
part++;
if (part < numParts) {
throw new ASN1Exception("AttributesPlusTerm: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the AttributesPlusTerm.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 102);
}
/**
* Returns a BER encoding of AttributesPlusTerm, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 2;
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
fields[x++] = sAttributes.berEncode();
fields[x] = sTerm.berEncode();
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the AttributesPlusTerm.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
int outputted = 0;
str.append("attributes ");
str.append(sAttributes);
outputted++;
if (0 < outputted) {
str.append(", ");
}
str.append("term ");
str.append(sTerm);
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,261 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>Close</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* Close ::=
* SEQUENCE {
* referenceId ReferenceId OPTIONAL
* closeReason CloseReason
* diagnosticInformation [3] IMPLICIT InternationalString OPTIONAL
* resourceReportFormat [4] IMPLICIT ResourceReportId OPTIONAL
* resourceReport [5] EXPLICIT ResourceReport OPTIONAL
* otherInfo OtherInformation OPTIONAL
* }
* </pre>
*/
public final class Close extends ASN1Any {
public ReferenceId sReferenceId; // optional
public CloseReason sCloseReason;
public InternationalString sDiagnosticInformation; // optional
public ResourceReportId sResourceReportFormat; // optional
public ResourceReport sResourceReport; // optional
public OtherInformation sOtherInfo; // optional
/**
* Default constructor for a Close.
*/
public Close() {
}
/**
* Constructor for a Close from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public Close(BEREncoding ber, boolean checkTag)
throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("Close: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
BERConstructed tagged;
if (numParts <= part) {
throw new ASN1Exception("Close: incomplete");
}
p = berConstructed.elementAt(part);
try {
sReferenceId = new ReferenceId(p, true);
part++;
} catch (ASN1Exception e) {
sReferenceId = null;
}
if (numParts <= part) {
throw new ASN1Exception("Close: incomplete");
}
p = berConstructed.elementAt(part);
sCloseReason = new CloseReason(p, true);
part++;
sDiagnosticInformation = null;
sResourceReportFormat = null;
sResourceReport = null;
sOtherInfo = null;
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 3 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
sDiagnosticInformation = new InternationalString(p, false);
part++;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 4 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
sResourceReportFormat = new ResourceReportId(p, false);
part++;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 5 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
try {
tagged = (BERConstructed) p;
} catch (ClassCastException e) {
throw new ASN1EncodingException("Close: bad BER encoding: s_resourceReport tag bad");
}
if (tagged.numberComponents() != 1) {
throw new ASN1EncodingException("Close: bad BER encoding: s_resourceReport tag bad");
}
sResourceReport = new ResourceReport(tagged.elementAt(0), true);
part++;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
try {
sOtherInfo = new OtherInformation(p, true);
part++;
} catch (ASN1Exception e) {
sOtherInfo = null;
}
if (part < numParts) {
throw new ASN1Exception("Close: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the Close.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of Close, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 1;
if (sReferenceId != null) {
numFields++;
}
if (sDiagnosticInformation != null) {
numFields++;
}
if (sResourceReportFormat != null) {
numFields++;
}
if (sResourceReport != null) {
numFields++;
}
if (sOtherInfo != null) {
numFields++;
}
BEREncoding[] fields = new BEREncoding[numFields];
int x = 0;
BEREncoding[] enc;
if (sReferenceId != null) {
fields[x++] = sReferenceId.berEncode();
}
fields[x++] = sCloseReason.berEncode();
if (sDiagnosticInformation != null) {
fields[x++] = sDiagnosticInformation.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 3);
}
if (sResourceReportFormat != null) {
fields[x++] = sResourceReportFormat.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 4);
}
if (sResourceReport != null) {
enc = new BEREncoding[1];
enc[0] = sResourceReport.berEncode();
fields[x++] = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 5, enc);
}
if (sOtherInfo != null) {
fields[x] = sOtherInfo.berEncode();
}
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the Close.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
int outputted = 0;
if (sReferenceId != null) {
str.append("referenceId ");
str.append(sReferenceId);
outputted++;
}
if (0 < outputted) {
str.append(", ");
}
str.append("closeReason ");
str.append(sCloseReason);
outputted++;
if (sDiagnosticInformation != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("diagnosticInformation ");
str.append(sDiagnosticInformation);
outputted++;
}
if (sResourceReportFormat != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("resourceReportFormat ");
str.append(sResourceReportFormat);
outputted++;
}
if (sResourceReport != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("resourceReport ");
str.append(sResourceReport);
outputted++;
}
if (sOtherInfo != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("otherInfo ");
str.append(sOtherInfo);
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,97 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>CloseReason</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* CloseReason ::=
* [211] IMPLICIT INTEGER
* </pre>
*/
public final class CloseReason extends ASN1Any {
public static final int E_FINISHED = 0;
public static final int E_SHUTDOWN = 1;
public static final int E_SYSTEM_PROBLEM = 2;
public static final int E_COST_LIMIT = 3;
public static final int E_RESOURCES = 4;
public static final int E_SECURITY_VIOLATION = 5;
public static final int E_PROTOCOL_ERROR = 6;
public static final int E_LACK_OF_ACTIVITY = 7;
public static final int E_PEER_ABORT = 8;
public static final int E_UNSPECIFIED = 9;
public ASN1Integer value;
/**
* Default constructor for a CloseReason.
*/
public CloseReason() {
}
/**
* Constructor for a CloseReason from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public CloseReason(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
if (checkTag) {
if (ber.tagGet() != 211 ||
ber.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("CloseReason: bad BER: tag=" + ber.tagGet() + " expected 211");
}
}
value = new ASN1Integer(ber, false);
}
/**
* Returns a BER encoding of the CloseReason.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 211);
}
/**
* Returns a BER encoding of CloseReason, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
return value.berEncode(tagType, tag);
}
/**
* Returns a new String object containing a text representing
* of the CloseReason.
*/
public String toString() {
return value.toString();
}
}

View file

@ -0,0 +1,243 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1Boolean;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1ObjectIdentifier;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>CompSpec</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* CompSpec ::=
* SEQUENCE {
* selectAlternativeSyntax [1] IMPLICIT BOOLEAN
* generic [2] IMPLICIT Specification OPTIONAL
* dbSpecific [3] IMPLICIT SEQUENCE OF CompSpec_dbSpecific OPTIONAL
* recordSyntax [4] IMPLICIT SEQUENCE OF OBJECT IDENTIFIER OPTIONAL
* }
* </pre>
*/
public final class CompSpec extends ASN1Any {
public ASN1Boolean sSelectAlternativeSyntax;
public Specification sGeneric; // optional
public CompSpecDbSpecific[] dbSpecifics; // optional
public ASN1ObjectIdentifier[] objectIdentifiers; // optional
/**
* Default constructor for a CompSpec.
*/
public CompSpec() {
}
/**
* Constructor for a CompSpec from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public CompSpec(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("CompSpec: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
if (numParts <= part) {
throw new ASN1Exception("CompSpec: incomplete");
}
p = berConstructed.elementAt(part);
if (p.tagGet() != 1 ||
p.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("CompSpec: bad tag in s_selectAlternativeSyntax\n");
}
sSelectAlternativeSyntax = new ASN1Boolean(p, false);
part++;
sGeneric = null;
dbSpecifics = null;
objectIdentifiers = null;
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 2 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
sGeneric = new Specification(p, false);
part++;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 3 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
try {
BERConstructed cons = (BERConstructed) p;
int parts = cons.numberComponents();
dbSpecifics = new CompSpecDbSpecific[parts];
int n;
for (n = 0; n < parts; n++) {
dbSpecifics[n] = new CompSpecDbSpecific(cons.elementAt(n), true);
}
} catch (ClassCastException e) {
throw new ASN1EncodingException("Bad BER");
}
part++;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
if (p.tagGet() == 4 &&
p.tagTypeGet() == BEREncoding.CONTEXT_SPECIFIC_TAG) {
try {
BERConstructed cons = (BERConstructed) p;
int parts = cons.numberComponents();
objectIdentifiers = new ASN1ObjectIdentifier[parts];
int n;
for (n = 0; n < parts; n++) {
objectIdentifiers[n] = new ASN1ObjectIdentifier(cons.elementAt(n), true);
}
} catch (ClassCastException e) {
throw new ASN1EncodingException("Bad BER");
}
part++;
}
if (part < numParts) {
throw new ASN1Exception("CompSpec: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the CompSpec.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of CompSpec, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 1;
if (sGeneric != null) {
numFields++;
}
if (dbSpecifics != null) {
numFields++;
}
if (objectIdentifiers != null) {
numFields++;
}
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
BEREncoding f2[];
int p;
fields[x++] = sSelectAlternativeSyntax.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 1);
if (sGeneric != null) {
fields[x++] = sGeneric.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 2);
}
if (dbSpecifics != null) {
f2 = new BEREncoding[dbSpecifics.length];
for (p = 0; p < dbSpecifics.length; p++) {
f2[p] = dbSpecifics[p].berEncode();
}
fields[x++] = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 3, f2);
}
if (objectIdentifiers != null) {
f2 = new BEREncoding[objectIdentifiers.length];
for (p = 0; p < objectIdentifiers.length; p++) {
f2[p] = objectIdentifiers[p].berEncode();
}
fields[x] = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 4, f2);
}
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the CompSpec.
*/
public String toString() {
int p;
StringBuilder str = new StringBuilder("{");
int outputted = 0;
str.append("selectAlternativeSyntax ");
str.append(sSelectAlternativeSyntax);
outputted++;
if (sGeneric != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("generic ");
str.append(sGeneric);
outputted++;
}
if (dbSpecifics != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("dbSpecific ");
str.append("{");
for (p = 0; p < dbSpecifics.length; p++) {
if (p != 0) {
str.append(", ");
}
str.append(dbSpecifics[p]);
}
str.append("}");
outputted++;
}
if (objectIdentifiers != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("recordSyntax ");
str.append("{");
for (p = 0; p < objectIdentifiers.length; p++) {
if (p != 0) {
str.append(", ");
}
str.append(objectIdentifiers[p]);
}
str.append("}");
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,144 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>CompSpec_dbSpecific</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* CompSpec_dbSpecific ::=
* SEQUENCE {
* db [1] EXPLICIT DatabaseName
* spec [2] IMPLICIT Specification
* }
* </pre>
*/
public final class CompSpecDbSpecific extends ASN1Any {
public DatabaseName sDb;
public Specification sSpec;
/**
* Constructor for a CompSpec_dbSpecific from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public CompSpecDbSpecific(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("CompSpec_dbSpecific: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
BERConstructed tagged;
if (numParts <= part) {
throw new ASN1Exception("CompSpec_dbSpecific: incomplete");
}
p = berConstructed.elementAt(part);
if (p.tagGet() != 1 ||
p.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException
("CompSpec_dbSpecific: bad tag in s_db\n");
}
try {
tagged = (BERConstructed) p;
} catch (ClassCastException e) {
throw new ASN1EncodingException
("CompSpec_dbSpecific: bad BER encoding: s_db tag bad\n");
}
if (tagged.numberComponents() != 1) {
throw new ASN1EncodingException
("CompSpec_dbSpecific: bad BER encoding: s_db tag bad\n");
}
sDb = new DatabaseName(tagged.elementAt(0), true);
part++;
if (numParts <= part) {
throw new ASN1Exception("CompSpec_dbSpecific: incomplete");
}
p = berConstructed.elementAt(part);
if (p.tagGet() != 2 ||
p.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException
("CompSpec_dbSpecific: bad tag in s_spec\n");
}
sSpec = new Specification(p, false);
part++;
if (part < numParts) {
throw new ASN1Exception("CompSpec_dbSpecific: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the CompSpec_dbSpecific.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of CompSpec_dbSpecific, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 2;
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
BEREncoding enc[];
enc = new BEREncoding[1];
enc[0] = sDb.berEncode();
fields[x++] = new BERConstructed(BEREncoding.CONTEXT_SPECIFIC_TAG, 1, enc);
fields[x] = sSpec.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 2);
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the CompSpec_dbSpecific.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
int outputted = 0;
str.append("db ");
str.append(sDb);
outputted++;
if (0 < outputted) {
str.append(", ");
}
str.append("spec ");
str.append(sSpec);
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,92 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>DatabaseName</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* DatabaseName ::=
* [105] IMPLICIT InternationalString
* </pre>
*/
public final class DatabaseName extends ASN1Any {
public InternationalString value;
/**
* Default constructor for a DatabaseName.
*/
public DatabaseName() {
}
/**
* Constructor for a DatabaseName from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public DatabaseName(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
// Check tag matches
if (checkTag) {
if (ber.tagGet() != 105 ||
ber.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("DatabaseName: bad BER: tag=" + ber.tagGet() + " expected 105\n");
}
}
value = new InternationalString(ber, false);
}
/**
* Returns a BER encoding of the DatabaseName.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 105);
}
/**
* Returns a BER encoding of DatabaseName, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
return value.berEncode(tagType, tag);
}
/**
* Returns a new String object containing a text representing
* of the DatabaseName.
*/
public String toString() {
return value.toString();
}
}

View file

@ -0,0 +1,137 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1ObjectIdentifier;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>DefaultDiagFormat</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* DefaultDiagFormat ::=
* SEQUENCE {
* diagnosticSetId OBJECT IDENTIFIER
* condition INTEGER
* addinfo DefaultDiagFormat_addinfo
* }
* </pre>
*/
public final class DefaultDiagFormat extends ASN1Any {
public ASN1ObjectIdentifier sDiagnosticSetId;
public ASN1Integer sCondition;
public DefaultDiagFormatAddinfo sAddinfo;
/**
* Constructor for a DefaultDiagFormat from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public DefaultDiagFormat(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("DefaultDiagFormat: bad BER form\n");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
if (numParts <= part) {
throw new ASN1Exception("DefaultDiagFormat: incomplete");
}
p = berConstructed.elementAt(part);
sDiagnosticSetId = new ASN1ObjectIdentifier(p, true);
part++;
if (numParts <= part) {
throw new ASN1Exception("DefaultDiagFormat: incomplete");
}
p = berConstructed.elementAt(part);
sCondition = new ASN1Integer(p, true);
part++;
if (numParts <= part) {
throw new ASN1Exception("DefaultDiagFormat: incomplete");
}
p = berConstructed.elementAt(part);
sAddinfo = new DefaultDiagFormatAddinfo(p, true);
part++;
if (part < numParts) {
throw new ASN1Exception("DefaultDiagFormat: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the DefaultDiagFormat.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of DefaultDiagFormat, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 3; // number of mandatories
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
fields[x++] = sDiagnosticSetId.berEncode();
fields[x++] = sCondition.berEncode();
fields[x] = sAddinfo.berEncode();
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the DefaultDiagFormat.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
int outputted = 0;
str.append("diagnosticSetId ");
str.append(sDiagnosticSetId);
outputted++;
if (0 < outputted) {
str.append(", ");
}
str.append("condition ");
str.append(sCondition);
outputted++;
if (0 < outputted) {
str.append(", ");
}
str.append("addinfo ");
str.append(sAddinfo);
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,113 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1VisibleString;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>DefaultDiagFormat_addinfo</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* DefaultDiagFormat_addinfo ::=
* CHOICE {
* v2Addinfo VisibleString
* v3Addinfo InternationalString
* }
* </pre>
*/
public final class DefaultDiagFormatAddinfo extends ASN1Any {
public ASN1VisibleString cV2Addinfo;
public InternationalString cV3Addinfo;
/**
* Constructor for a DefaultDiagFormat_addinfo from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public DefaultDiagFormatAddinfo(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
cV2Addinfo = null;
cV3Addinfo = null;
try {
cV2Addinfo = new ASN1VisibleString(ber, checkTag);
return;
} catch (ASN1Exception e) {
// failed to decode, continue on
}
try {
cV3Addinfo = new InternationalString(ber, checkTag);
return;
} catch (ASN1Exception e) {
// failed to decode, continue on
}
throw new ASN1Exception("DefaultDiagFormat_addinfo: bad BER encoding: choice not matched");
}
/**
* Returns a BER encoding of DefaultDiagFormat_addinfo.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
BEREncoding chosen = null;
if (cV2Addinfo != null) {
chosen = cV2Addinfo.berEncode();
}
if (cV3Addinfo != null) {
if (chosen != null) {
throw new ASN1Exception("CHOICE multiply set");
}
chosen = cV3Addinfo.berEncode();
}
if (chosen == null) {
throw new ASN1Exception("CHOICE not set");
}
return chosen;
}
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
throw new ASN1EncodingException("DefaultDiagFormat_addinfo: cannot implicitly tag");
}
/**
* Returns a new String object containing a text representing
* of the DefaultDiagFormat_addinfo.
*/
public String toString() {
StringBuilder str = new StringBuilder("{");
boolean found = false;
if (cV2Addinfo != null) {
found = true;
str.append("v2Addinfo ");
str.append(cV2Addinfo);
}
if (cV3Addinfo != null) {
if (found) {
str.append("<ERROR: multiple CHOICE: v3Addinfo> ");
}
str.append("v3Addinfo ");
str.append(cV3Addinfo);
}
str.append("}");
return str.toString();
}
}

View file

@ -0,0 +1,218 @@
package org.xbib.io.iso23950.v3;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1EncodingException;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.BERConstructed;
import org.xbib.asn1.BEREncoding;
/**
* Class for representing a <code>DeleteResultSetRequest</code> from <code>Z39-50-APDU-1995</code>.
* <pre>
* DeleteResultSetRequest ::=
* SEQUENCE {
* referenceId ReferenceId OPTIONAL
* deleteFunction [32] IMPLICIT INTEGER
* resultSetList SEQUENCE OF ResultSetId OPTIONAL
* otherInfo OtherInformation OPTIONAL
* }
* </pre>
*/
public final class DeleteResultSetRequest extends ASN1Any {
// Enumerated constants for deleteFunction
public static final int E_LIST = 0;
public static final int E_ALL = 1;
public ReferenceId referenceId; // optional
public ASN1Integer sDeleteFunction;
public ResultSetId[] sResultSetList; // optional
public OtherInformation sOtherInfo; // optional
/**
* Constructor for a DeleteResultSetRequest from a BER encoding.
*
* @param ber the BER encoding.
* @param checkTag will check tag if true, use false
* if the BER has been implicitly tagged. You should
* usually be passing true.
* @throws ASN1Exception if the BER encoding is bad.
*/
public DeleteResultSetRequest(BEREncoding ber, boolean checkTag) throws ASN1Exception {
super(ber, checkTag);
}
/**
* Initializing object from a BER encoding.
* This method is for internal use only. You should use
* the constructor that takes a BEREncoding.
*
* @param ber the BER to decode.
* @param checkTag if the tag should be checked.
* @throws ASN1Exception if the BER encoding is bad.
*/
public void berDecode(BEREncoding ber, boolean checkTag) throws ASN1Exception {
BERConstructed berConstructed;
try {
berConstructed = (BERConstructed) ber;
} catch (ClassCastException e) {
throw new ASN1EncodingException("DeleteResultSetRequest: bad BER form");
}
int numParts = berConstructed.numberComponents();
int part = 0;
BEREncoding p;
if (numParts <= part) {
throw new ASN1Exception("DeleteResultSetRequest: incomplete");
}
p = berConstructed.elementAt(part);
try {
referenceId = new ReferenceId(p, true);
part++;
} catch (ASN1Exception e) {
referenceId = null;
}
if (numParts <= part) {
throw new ASN1Exception("DeleteResultSetRequest: incomplete");
}
p = berConstructed.elementAt(part);
if (p.tagGet() != 32 ||
p.tagTypeGet() != BEREncoding.CONTEXT_SPECIFIC_TAG) {
throw new ASN1EncodingException("DeleteResultSetRequest: bad tag in s_deleteFunction");
}
sDeleteFunction = new ASN1Integer(p, false);
part++;
sResultSetList = null;
sOtherInfo = null;
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
try {
try {
BERConstructed cons = (BERConstructed) p;
int parts = cons.numberComponents();
sResultSetList = new ResultSetId[parts];
int n;
for (n = 0; n < parts; n++) {
sResultSetList[n] = new ResultSetId(cons.elementAt(n), true);
}
} catch (ClassCastException e) {
throw new ASN1EncodingException("Bad BER");
}
part++;
} catch (ASN1Exception e) {
sResultSetList = null;
}
if (numParts <= part) {
return;
}
p = berConstructed.elementAt(part);
try {
sOtherInfo = new OtherInformation(p, true);
part++; // yes, consumed
} catch (ASN1Exception e) {
sOtherInfo = null; // no, not present
}
if (part < numParts) {
throw new ASN1Exception("DeleteResultSetRequest: bad BER: extra data " + part + "/" + numParts + " processed");
}
}
/**
* Returns a BER encoding of the DeleteResultSetRequest.
*
* @return The BER encoding.
* @throws ASN1Exception Invalid or cannot be encoded.
*/
public BEREncoding berEncode() throws ASN1Exception {
return berEncode(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG);
}
/**
* Returns a BER encoding of DeleteResultSetRequest, implicitly tagged.
*
* @param tagType The type of the implicit tag.
* @param tag The implicit tag.
* @return The BER encoding of the object.
* @throws ASN1Exception When invalid or cannot be encoded.
*/
public BEREncoding berEncode(int tagType, int tag) throws ASN1Exception {
int numFields = 1;
if (referenceId != null) {
numFields++;
}
if (sResultSetList != null) {
numFields++;
}
if (sOtherInfo != null) {
numFields++;
}
BEREncoding fields[] = new BEREncoding[numFields];
int x = 0;
BEREncoding f2[];
int p;
if (referenceId != null) {
fields[x++] = referenceId.berEncode();
}
fields[x++] = sDeleteFunction.berEncode(BEREncoding.CONTEXT_SPECIFIC_TAG, 32);
if (sResultSetList != null) {
f2 = new BEREncoding[sResultSetList.length];
for (p = 0; p < sResultSetList.length; p++) {
f2[p] = sResultSetList[p].berEncode();
}
fields[x++] = new BERConstructed(BEREncoding.UNIVERSAL_TAG, ASN1Sequence.SEQUENCE_TAG, f2);
}
if (sOtherInfo != null) {
fields[x] = sOtherInfo.berEncode();
}
return new BERConstructed(tagType, tag, fields);
}
/**
* Returns a new String object containing a text representing
* of the DeleteResultSetRequest.
*/
public String toString() {
int p;
StringBuilder str = new StringBuilder("{");
int outputted = 0;
if (referenceId != null) {
str.append("referenceId ");
str.append(referenceId);
outputted++;
}
if (0 < outputted) {
str.append(", ");
}
str.append("deleteFunction ");
str.append(sDeleteFunction);
outputted++;
if (sResultSetList != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("resultSetList ");
str.append("{");
for (p = 0; p < sResultSetList.length; p++) {
if (p != 0) {
str.append(", ");
}
str.append(sResultSetList[p]);
}
str.append("}");
outputted++;
}
if (sOtherInfo != null) {
if (0 < outputted) {
str.append(", ");
}
str.append("otherInfo ");
str.append(sOtherInfo);
}
str.append("}");
return str.toString();
}
}

Some files were not shown because too many files have changed in this diff Show more