这篇文章是以前在 XPage 中使用 .properties 资源文件 ResourceBundle 的继承。在这篇文章中,所有荣誉都归功于 Sean Cullm、Matt White、Julian Robichaus 。我遇到了错误: **Base64 byte stream contains invalid data or is too large to store in a single note item**
一些键:值对非常大。为了解决字符串被截断或抛出上述错误的问题,我转移了一个 JAVA 解决方案来解决似乎是一个 LotusScript 问题。Java解决方案:
JavaAgent 扩展了 AgentBase:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Vector;
import lotus.domino.AgentBase;
import lotus.domino.AgentContext;
import lotus.domino.Database;
import lotus.domino.DateTime;
import lotus.domino.DxlImporter;
import lotus.domino.Log;
import lotus.domino.NotesException;
import lotus.domino.Session;
import lotus.domino.Stream;
import lotus.domino.View;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;
public class JavaAgent extends AgentBase {
public Database db;
public View view;
static DxlImporter importer = null;
Log log;
DateTime dt;
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// Document contextDoc = agentContext.getDocumentContext();
log = session.createLog("Agent Log");
log.openAgentLog();
this.db = agentContext.getCurrentDatabase();
this.view = db.getView("dojoprivotdatadocs");
importer = session.createDxlImporter();
importer.setReplaceDbProperties(true);
importer.setReplicaRequiredForReplaceOrUpdate(false);
importer.setAclImportOption(DxlImporter.DXLIMPORTOPTION_IGNORE);
importer
.setDesignImportOption(DxlImporter.DXLIMPORTOPTION_REPLACE_ELSE_CREATE);
importer
.setDocumentImportOption(DxlImporter.DXLIMPORTOPTION_IGNORE);
// importer.importDxl(generateDXL("", "", db.getReplicaID()), db);
importer.importDxl(generateDXL("", "", ""), db);
view.setAutoUpdate(true);
view.recycle();
db.recycle();
} catch (Exception e) {
e.printStackTrace();
System.out.println("end__" + e.getMessage());
} finally {
try {
System.out.println(importer.getLog());
} catch (Exception e) {
e.printStackTrace();
System.out.println("final: " + e.getMessage());
}
}
}
public Stream generateDXL(String data, final String libName,
final String dbReplicaId) throws NotesException {
Session session = getSession();
Stream dxlStream = session.createStream();
//NOTE: I left the raw DXL generated by an NotesNoteCollection export
//the import DXL is not verbose like the exported DXL, the DXL exported is commented out
try {
this.view.refresh();
this.view.setAutoUpdate(false);
dxlStream.writeText("<?xml version='1.0' encoding='utf-8'?>");
dxlStream
.writeText("<!DOCTYPE database SYSTEM 'xmlschemas/domino_9_0_1.dtd'>");
/**
* dxl .append("<database xmlns='http://www.lotus.com/dxl' version='9.0' maintenanceversion='1.0' replicaid='"
* + dbReplicaId +"' path='CN=dom001/OU=SERVER/O=PC!!SSH\\ESA\\PolarColFileData.nsf' title='Polar Col File Data'>"
* );
**/
dxlStream
.writeText("<database xmlns='http://www.lotus.com/dxl' replicaid='882580D6006A6F64'>");
/**
* dxl .append("<fileresource name='base64.properties' noreplace='false' publicaccess='false' designerversion='9.0.1'>"
* );
**/
dxlStream
.writeText("<fileresource name='dojoPivotData.properties' noreplace='false' publicaccess='false' charset='ISO-8859-1'>");
// dxlStream
// .writeText("<created><datetime dst='true'>20171214T101814,59-07</datetime></created>");
dxlStream.writeText("<filedata>");
// Base64 base64 = new Base64();
dxlStream.writeText(Base64.encode(getViewEntires().readText()));
dxlStream.writeText("</filedata></fileresource></database>");
} catch (NotesException ne) {
ne.printStackTrace();
System.out.println("generateDXL:: " + ne.getMessage());
} catch (Exception e) {
e.printStackTrace();
System.out.println("generateDXL:: " + e.getMessage());
}
return dxlStream;
}
public Stream getViewEntires() throws NotesException {
Stream base64Stream = getSession().createStream();
String eString = "";
try {
ViewEntryCollection vec = this.view.getAllEntries();
ViewEntry tmpentry;
ViewEntry entry = vec.getFirstEntry();
while (entry != null) {
Vector colvals = entry.getColumnValues();
base64Stream
.writeText(colvals.get(0).toString(), Stream.EOL_CR);
tmpentry = vec.getNextEntry();
entry.recycle();
entry = tmpentry;
}
dt = getSession().createDateTime("Today");
dt.setNow();
base64Stream.writeText("@generated=" + dt.getDateOnly() + " "
+ dt.getTimeOnly() + " TZ:" + dt.getTimeZone(),
Stream.EOL_CR);
dt.recycle();
base64Stream.setPosition(0);
} catch (NotesException ne) {
ne.printStackTrace();
System.out.println("getViewEntires:: " + eString + ": "
+ ne.getMessage());
} catch (Exception e) {
e.printStackTrace();
System.out.println("getViewEntires:: " + eString + ": "
+ e.getMessage());
}
return base64Stream;
}
/**
* converts a integer to a byte array in little endian order
*
* @param i
* integer to convert
* @return byte array
*/
static byte[] toBytes(final int i) {
ByteBuffer b = ByteBuffer.allocate(4);
b.order(ByteOrder.LITTLE_ENDIAN);
b.putInt(i);
return b.array();
}
}
ASCII.java
/*
* Copyright IBM Corp. 2012-2013
*
* 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.
*/
/**
* Ascii constants.
* <p>
* Some useful constants.
* </p>
*
* @ibm-not-published
*/
public interface Ascii {
public static final byte CASE_OFFSET = 32;
public static final byte A = 65;
public static final byte B = 66;
public static final byte C = 67;
public static final byte D = 68;
public static final byte E = 69;
public static final byte F = 70;
public static final byte G = 71;
public static final byte H = 72;
public static final byte I = 73;
public static final byte J = 74;
public static final byte K = 75;
public static final byte L = 76;
public static final byte M = 77;
public static final byte N = 78;
public static final byte O = 79;
public static final byte P = 80;
public static final byte Q = 81;
public static final byte R = 82;
public static final byte S = 83;
public static final byte T = 84;
public static final byte U = 85;
public static final byte V = 86;
public static final byte W = 87;
public static final byte X = 88;
public static final byte Y = 89;
public static final byte Z = 90;
public static final byte a = 97;
public static final byte b = 98;
public static final byte c = 99;
public static final byte d = 100;
public static final byte e = 101;
public static final byte f = 102;
public static final byte g = 103;
public static final byte h = 104;
public static final byte i = 105;
public static final byte j = 106;
public static final byte k = 107;
public static final byte l = 108;
public static final byte m = 109;
public static final byte n = 110;
public static final byte o = 111;
public static final byte p = 112;
public static final byte q = 113;
public static final byte r = 114;
public static final byte s = 115;
public static final byte t = 116;
public static final byte u = 117;
public static final byte v = 118;
public static final byte w = 119;
public static final byte x = 120;
public static final byte y = 121;
public static final byte z = 122;
public static final byte ZERO = 48;
public static final byte ONE = 49;
public static final byte TWO = 50;
public static final byte THREE = 51;
public static final byte FOUR = 52;
public static final byte FIVE = 53;
public static final byte SIX = 54;
public static final byte SEVEN = 55;
public static final byte EIGHT = 56;
public static final byte NINE = 57;
public static final byte TAB = 9;
public static final byte LF = 10;
public static final byte FF = 12;
public static final byte CR = 13;
public static final byte SPACE = 32;
public static final byte PERIOD = 46;
public static final byte SLASH = 47;
public static final byte BACK_SLASH = 92;
public static final byte COLON = 58;
public static final byte SEMICOLON = 59;
public static final byte EQUALS = 61;
public static final byte QUOTE = 34;
public static final byte LT = 60;
public static final byte GT = 62;
public static final byte OP = 40;
public static final byte CP = 41;
public static final byte AT = 64;
public static final byte UNDERSCORE = 95;
public static final byte STAR = 42;
public static final byte PERCENT = 37;
public static final byte HYPHEN = 45;
public static final byte PLUS = 43;
public static final byte OPEN_CURLY = 123;
public static final byte CLOSE_CURLY = 125;
public static final byte OPEN_ANGLE = 60;
public static final byte CLOSE_ANGLE = 62;
/** The CR/LF pair. */
public static final byte[] CRLF = { CR, LF };
}
Base64OutputStream.java
/*
* Copyright IBM Corp. 2012-2013
*
* 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.
*/
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* A Base64 content transfer encoding filter stream.
* <p>
* From RFC 2045, section 6.8:
* <p>
* The Base64 Content-Transfer-Encoding is designed to represent arbitrary
* sequences of octets in a form that need not be humanly readable. The encoding
* and decoding algorithms are simple, but the encoded data are consistently
* only about 33 percent larger than the unencoded data.
*
* @ibm-api
*/
public class Base64OutputStream extends FilterOutputStream {
private final byte[] _buffer;
private int _buflen;
private int _count;
private final int _lineLength;
/**
* Default constructor.
*
* @param out
* the underlying output stream to encode
* @pre out != null
* @post out != null
*/
public Base64OutputStream(OutputStream out) {
this(out, Integer.MAX_VALUE);
}
/**
* Constructor.
*
* @param out
* the underlying output stream to encode
* @param lineLength
* the line length
* @pre out != null
* @pre lineLength > 0
* @post out != null
*/
public Base64OutputStream(OutputStream out, int lineLength) {
super(out);
_buflen = 0;
_count = 0;
_buffer = new byte[3];
_lineLength = lineLength;
}
/**
* Writes the specified byte to this output stream.
*
* @param ch
* character to write/encode
* @throws IOException
* IO Exception occurred
* @pre out != null
* @post out != null
*/
public void write(int ch) throws IOException {
_buffer[_buflen++] = (byte) ch;
if (_buflen == 3) {
encode();
_buflen = 0;
}
}
/**
* Writes <code>b.length</code> bytes from the specified byte array to this
* output stream.
*
* @param b
* buffer to write/encode
* @throws IOException
* IO Exception occurred
* @pre out != null
* @post out != null
*/
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
/**
* Writes <code>len</code> bytes from the specified byte array starting at
* offset <code>off</code> to this output stream.
*
* @param b
* buffer to write/encode
* @param off
* offset to start of buffer to write/encode
* @param len
* number of bytes from buffer to write/encode
* @throws IOException
* IO Exception occurred
* @pre off < b.length
* @pre off+len < b.length
* @pre out != null
* @post out != null
*/
public void write(byte[] b, int off, int len) throws IOException {
for (int i = 0; i < len; i++) {
write(b[off + i]);
}
}
/**
* Flushes this output stream and forces any buffered output bytes to be
* written out.
*
* @throws IOException
* IO Exception occurred
* @pre out != null
* @post _buflen == 0
*/
public void flush() throws IOException {
if (_buflen > 0) {
encode();
_buflen = 0;
}
out.flush();
}
/**
* Closes this output stream and releases any system resources associated
* with this stream.
*
* @throws IOException
* IO Exception occurred
* @pre out != null
* @post $none
*/
public void close() throws IOException {
flush();
out.close();
}
/**
* Encode current buffer bytes
*
* @throws IOException
* IO Exception occurred
* @pre out != null
*/
private void encode() throws IOException {
if ((_count + 4) > _lineLength) {
out.write(Ascii.CR);
out.write(Ascii.LF);
_count = 0;
}
if (_buflen == 1) {
byte b = _buffer[0];
int i = 0;
out.write(IoConstants.B64_SRC_MAP[b >>> 2 & 0x3f]);
out
.write(IoConstants.B64_SRC_MAP[(b << 4 & 0x30)
+ (i >>> 4 & 0xf)]);
out.write(Ascii.EQUALS);
out.write(Ascii.EQUALS);
} else if (_buflen == 2) {
byte b1 = _buffer[0], b2 = _buffer[1];
int i = 0;
out.write(IoConstants.B64_SRC_MAP[b1 >>> 2 & 0x3f]);
out.write(IoConstants.B64_SRC_MAP[(b1 << 4 & 0x30)
+ (b2 >>> 4 & 0xf)]);
out.write(IoConstants.B64_SRC_MAP[(b2 << 2 & 0x3c)
+ (i >>> 6 & 0x3)]);
out.write(Ascii.EQUALS);
} else {
byte b1 = _buffer[0], b2 = _buffer[1], b3 = _buffer[2];
out.write(IoConstants.B64_SRC_MAP[b1 >>> 2 & 0x3f]);
out.write(IoConstants.B64_SRC_MAP[(b1 << 4 & 0x30)
+ (b2 >>> 4 & 0xf)]);
out.write(IoConstants.B64_SRC_MAP[(b2 << 2 & 0x3c)
+ (b3 >>> 6 & 0x3)]);
out.write(IoConstants.B64_SRC_MAP[b3 & 0x3f]);
}
_count += 4;
}
}
Base64.java
/*
* Copyright IBM Corp. 2012-2013
*
* 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.
*/
import java.io.IOException;
/**
* Encodes and decodes to and from Base64 notation.
*
* @ibm-api
*/
public class Base64 {
/**
* Decode a base64 string to an ascii string.
*
* @param base64str
* the string to decode
* @return
* @ibm-api
*/
public static String decode(String base64str) {
try {
StringInputStream bais = new StringInputStream(base64str);
Base64.InputStream b64 = new Base64.InputStream(bais);
StringBuffer buf = new StringBuffer();
int byt;
while ((byt = b64.read()) >= 0) {
buf.append((char) byt);
}
return buf.toString();
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
}
/**
* Encode a string to base64.
*
* @param str
* the string to encode
* @return
* @ibm-api
*/
public static String encode(String str) {
try {
StringBuidlerOutputStream baos = new StringBuidlerOutputStream(str
.length() * 3 / 2);
Base64.OutputStream b64 = new Base64.OutputStream(baos);
int len = str.length();
for (int i = 0; i < len; i++) {
int c = (str.charAt(i)) & 0x00FF;
b64.write(c);
}
b64.flushBuffer();
return baos.builder.toString();
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
}
public static class StringInputStream extends java.io.InputStream {
private final String str;
private int ptr;
public StringInputStream(String str) {
this.str = str;
}
public int read() throws IOException {
if (ptr < str.length()) {
return str.charAt(ptr++);
}
return -1;
}
}
public static class StringBufferOutputStream extends java.io.OutputStream {
private final StringBuffer buffer;
public StringBufferOutputStream(int size) {
this.buffer = new StringBuffer(size);
}
public StringBuffer getStringBuffer() {
return buffer;
}
public void write(int b) throws IOException {
buffer.append((char) b);
}
}
public static class StringBuidlerOutputStream extends java.io.OutputStream {
private final StringBuilder builder;
public StringBuidlerOutputStream(int size) {
this.builder = new StringBuilder(size);
}
public StringBuilder getStringBuilder() {
return builder;
}
public void write(int b) throws IOException {
builder.append((char) b);
}
}
public static class OutputStream extends Base64OutputStream {
public OutputStream(java.io.OutputStream out) {
super(out);
}
public void flushBuffer() throws IOException {
flush();
}
}
public static class InputStream extends Base64InputStream {
public InputStream(java.io.InputStream in) {
super(in);
}
}
}
Base64InputStream.java
/*
* Copyright IBM Corp. 2012-2013
*
* 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.
*/
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* A Base64 content transfer encoding filter stream.
* <p>
* From RFC 2045, section 6.8:
* <p>
* The Base64 Content-Transfer-Encoding is designed to represent arbitrary
* sequences of octets in a form that need not be humanly readable. The encoding
* and decoding algorithms are simple, but the encoded data are consistently
* only about 33 percent larger than the unencoded data.
*
* @ibm-api
*/
public class Base64InputStream extends FilterInputStream {
private final byte[] _buffer;
private int _buflen;
private int _index;
private final byte[] _decodeBuf;
/**
* Constructs an input stream that decodes an underlying Base64-encoded
* stream.
*
* @param in
* the Base64-encoded stream
* @ibm-api
*/
public Base64InputStream(InputStream in) {
super(in);
_buflen = 0;
_index = 0;
_decodeBuf = new byte[4];
_buffer = new byte[3];
}
/**
* Reads the next byte of data from the input stream.
*
* @throws IOException
* IO Exception occurred
* @return next byte in data stream
*/
public int read() throws IOException {
if (_index >= _buflen) {
decode();
if (_buflen == 0) {
return -1;
}
_index = 0;
}
return _buffer[_index++] & 0xFF;
}
/**
* Reads up to len bytes of data from the input stream into an array of
* bytes.
*
* @param b
* buffer to put data
* @param off
* offset to start of buffer
* @param len
* number of bytes from buffer
* @throws IOException
* IO Exception occurred
* @return number of bytes read
*/
public int read(byte[] b, int off, int len) throws IOException {
try {
int l = 0;
for (; l < len; l++) {
int ch = read();
if (ch == -1) {
if (l == 0) {
return -1;
} else {
break;
}
}
b[off + l] = (byte) ch;
}
return l;
} catch (IOException ioe) {
return -1;
}
}
/**
* Returns the number of bytes that can be read (or skipped over) from this
* input stream without blocking by the next caller of a method for this
* input stream.
*
* @throws IOException
* IO Exception occurred
* @return number of bytes that can be read
*/
public int available() throws IOException {
return (in.available() * 3) / 4 + (_buflen - _index);
}
/**
* Decode Base64 encoded buffer
*
* @throws IOException
* IO Exception occurred
*/
private void decode() throws IOException {
_buflen = 0;
// Loop until we hit EOF or non-line-termination char
int ch = Ascii.LF;
while (ch == Ascii.LF || ch == Ascii.CR) {
ch = in.read();
if (ch == -1) {
return;
}
}
_decodeBuf[0] = (byte) ch;
int j = 3, l;
for (int k = 1; (l = in.read(_decodeBuf, k, j)) != j; k += l) {
if (l == -1) {
throw new IOException("Base64 encoding error"); // $NLS-Base64InputStream.Base64encodingerror-1$
}
j -= l;
}
byte b0 = IoConstants.B64_DST_MAP[_decodeBuf[0] & 0xFF];
byte b2 = IoConstants.B64_DST_MAP[_decodeBuf[1] & 0xFF];
_buffer[_buflen++] = (byte) (b0 << 2 & 0xfc | b2 >>> 4 & 0x3);
if (_decodeBuf[2] != Ascii.EQUALS) {
b0 = b2;
b2 = IoConstants.B64_DST_MAP[_decodeBuf[2] & 0xFF];
_buffer[_buflen++] = (byte) (b0 << 4 & 0xf0 | b2 >>> 2 & 0xf);
if (_decodeBuf[3] != Ascii.EQUALS) {
byte b1 = b2;
b2 = IoConstants.B64_DST_MAP[_decodeBuf[3] & 0xFF];
_buffer[_buflen++] = (byte) (b1 << 6 & 0xc0 | b2 & 0x3f);
}
}
}
}
IoConstants.java
/*
* Copyright IBM Corp. 2012-2013
*
* 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.
*/
/**
* Useful constants for base64 package.
*
* @ibm-not-published
*/
public class IoConstants {
/**
* RFC822 requires that header lines are limited to 998 octets (excluding
* CRLF)
*/
public static final int MAX_RFC822_LINE_LENGTH = 998;
/**
* RFC 2822 requires that body content lines can never be more than 998
* octets (excluding CRLF)
*/
public static final int MAX_RFC2822_LINE_LENGTH = 998;
/**
* Map used for Base64 encoding
*/
public static final char[] B64_SRC_MAP = { 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '+', '/' };
/**
* Map used for Base64 decoding
*/
public static final byte[] B64_DST_MAP = new byte[256];
/**
* Char array used in decimal to hexidecimal conversion.
*/
public static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/** Construct mapping from source to destination maps */
static {
for (int i = 0; i < B64_DST_MAP.length; i++) {
B64_DST_MAP[i] = -1;
}
for (int i = 0; i < B64_SRC_MAP.length; i++) {
B64_DST_MAP[B64_SRC_MAP[i]] = (byte) i;
}
}
}