/*
* � Copyright IBM Corp. 2011
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.ibm.domino.services.content;
import static com.ibm.domino.services.HttpServiceConstants.CONTENTTYPE_TEXT_HTML;
import static com.ibm.domino.services.HttpServiceConstants.HEADER_CONTENT_CONTENT_DISPOSITION;
import static com.ibm.domino.services.HttpServiceConstants.HEADER_CONTENT_TYPE;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_ATTACHMENTS;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_AUTHORS;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_CONTENT;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_CONTENTTYPE;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_CREATED;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_DATA;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_FORM;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_HREF;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_MODIFIED;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_NOTEID;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_PARENTID;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_TYPE;
import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_UNID;
import static com.ibm.domino.services.rest.RestServiceConstants.ITEM_FILE;
import static com.ibm.domino.services.rest.RestServiceConstants.ITEM_FONTS;
import static com.ibm.domino.services.rest.RestServiceConstants.ITEM_FORM;
import static com.ibm.domino.services.rest.RestServiceConstants.TYPE_DATETIME;
import static com.ibm.domino.services.rest.RestServiceConstants.TYPE_MULTIPART;
import static com.ibm.domino.services.rest.RestServiceConstants.TYPE_RICHTEXT;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;
import lotus.domino.DateTime;
import lotus.domino.Document;
import lotus.domino.Form;
import lotus.domino.Item;
import lotus.domino.MIMEEntity;
import lotus.domino.MIMEHeader;
import lotus.domino.NotesException;
import lotus.domino.RichTextItem;
import com.ibm.commons.util.StringUtil;
import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.domino.commons.json.JsonMimeEntityAdapter;
import com.ibm.domino.commons.json.JsonMimeEntityAdapter.ParserContext;
import com.ibm.domino.commons.mime.MimeEntityHelper;
import com.ibm.domino.services.ServiceException;
import com.ibm.domino.services.rest.RestServiceConstants;
import com.ibm.domino.services.rest.das.document.DocumentParameters;
import com.ibm.domino.services.rest.das.document.RestDocumentItem;
import com.ibm.domino.services.rest.das.document.RestDocumentService;
import com.ibm.domino.services.util.JsonWriter;
import com.ibm.xsp.model.domino.DominoUtils;
public class JsonDocumentContent extends JsonContent {
private RestDocumentService service;
private Document document;
private boolean strongType;
private String rtType;
private String baseUri;
private static final SimpleDateFormat DATETIME_FORMAT = getDateTimeFormatter();
private static final int DATETIME_LENGTH = "2015-02-03T17:22:01Z".length(); //$NON-NLS-1$
public JsonDocumentContent(Document document) {
this.document = document;
}
public JsonDocumentContent(Document document, RestDocumentService service) {
this.document = document;
this.service = service;
}
/**
* Older version of writeDocumentAsJson for compatibility with existing callers.
*
* @param jsonWriter
* @param sysItems
* @param defItems
* @param custItems
* @param strongType
* @param rtType
* @param baseUri
* @throws IOException
* @throws ServiceException
* @throws NotesException
*/
public void writeDocumentAsJson(JsonWriter jsonWriter, int sysItems, boolean defItems,
List<RestDocumentItem> custItems, boolean strongType, String rtType, String baseUri)
throws IOException, ServiceException, NotesException {
writeDocumentAsJson(jsonWriter, sysItems, defItems,
null, // No item filter
false, // By default, do not lowercase item names
custItems, strongType, rtType, baseUri);
}
/**
* Emit JSON output for a Notes document.
*
* Called by Document Service and Document Resource for:
* GET Requests.
*
* @param jsonWriter - JSON Writer.
* @param sysItems - Emit system items.
* @param defItems - Emit default items.
* @param custItems - Emit custom items.
* @param lowercaseItems - Force item names to lower case
* @param strongtype - Use strong type for objects.
* @param rtType - Use JSON/MIME output for rich text and mime items.
* @param baseUri - Use to generate document links.
* @throws IOException
* @throws ServiceException
* @throws NotesException
*/
public void writeDocumentAsJson(JsonWriter jsonWriter, int sysItems, boolean defItems,
List<String> defItemFilter,
boolean lowercaseItems, List<RestDocumentItem> custItems,
boolean strongType, String rtType, String baseUri)
throws IOException, ServiceException, NotesException {
jsonWriter.startObject();
try {
this.strongType = strongType;
this.rtType = rtType;
this.baseUri = baseUri;
writeSystemItems(jsonWriter, sysItems);
writeItems(jsonWriter, defItems, defItemFilter, lowercaseItems, custItems);
} finally {
jsonWriter.endObject();
}
}
protected void writeSystemItems(JsonWriter jsonWriter, int sysItem)
throws IOException, NotesException, ServiceException {
// Write the system properties.
if (StringUtil.isNotEmpty(baseUri)) {
writeProperty(jsonWriter, ATTR_HREF, baseUri + "/" + document.getUniversalID()); // $NON-NLS-1$
}
if ((sysItem & DocumentParameters.SYS_ITEM_UNID)!=0) {
writeProperty(jsonWriter, ATTR_UNID, document.getUniversalID());
}
if ((sysItem & DocumentParameters.SYS_ITEM_NOTEID)!=0) {
writeProperty(jsonWriter, ATTR_NOTEID, document.getNoteID());
}
if ((sysItem & DocumentParameters.SYS_ITEM_PARENTID)!=0 && document.isResponse()) {
writeProperty(jsonWriter, ATTR_PARENTID, document.getParentDocumentUNID());
}
if ((sysItem & DocumentParameters.SYS_ITEM_CREATED)!=0) {
writeProperty(jsonWriter, ATTR_CREATED, document.getCreated());
}
if ((sysItem & DocumentParameters.SYS_ITEM_MODIFIED)!=0) {
writeProperty(jsonWriter, ATTR_MODIFIED, document.getLastModified());
}
if ((sysItem & DocumentParameters.SYS_ITEM_AUTHORS)!=0) {
writeProperty(jsonWriter, ATTR_AUTHORS, document.getAuthors());
}
if ((sysItem & DocumentParameters.SYS_ITEM_FORM)!=0) {
String form = document.getItemValueString(ITEM_FORM);
if (form != null && form.length() > 0) {
writeProperty(jsonWriter, ATTR_FORM, form);
}
}
if ((sysItem & DocumentParameters.SYS_ITEM_HIDDEN)!=0) {
writeHiddenSystemItems(jsonWriter, document);
}
}
protected void writeHiddenSystemItems(JsonWriter jsonWriter, Document document)
throws IOException, ServiceException {
try {
Vector<?> items = document.getItems();
for (int i = 0; i < items.size(); ++i) {
Item item = (Item)items.get(i);
String itemName = item.getName();
if (itemName.charAt(0) == '$') {
// String text = item.getText();
// if (text.length() > 0) {
// writeProperty(jsonWriter, itemName, text);
// }
if (itemName.equalsIgnoreCase(ITEM_FILE)) {
// Ignore $FILE item.
}
if (itemName.equalsIgnoreCase(ITEM_FONTS)) {
// Ignore $FONTS item.
} else {
writeItem(jsonWriter, item, false);
}
}
}
} catch (NotesException ex) {
throw new ServiceException(ex);
}
}
protected void writeItems(JsonWriter jsonWriter, boolean defItems, List<String> defItemFilter,
boolean lowercaseItems, List<RestDocumentItem> custItems)
throws IOException, ServiceException, NotesException {
@SuppressWarnings("unchecked") // // $NON-NLS-1$
Vector<Item> items = document.getItems();
// Read the default items
if (defItems) {
for (Item item: items) {
String itemName = item.getName();
if (itemName.charAt(0) == '$') { // $NON-NLS-1$
// Written in System Items.
}
else if (itemName.equalsIgnoreCase(ITEM_FORM)) {
// Written in System Items.
}
else if ( defItemFilter == null || defItemFilter.contains(itemName.toLowerCase())) {
writeItem(jsonWriter, item, lowercaseItems);
}
}
}
// Calculate the custom items
if (custItems != null) {
for (RestDocumentItem custItem : custItems) {
String name = custItem.getName();
Object itemValue = custItem.evaluate(service, document);
writeProperty(jsonWriter, name, itemValue);
}
}
}
protected void writeItem(JsonWriter jsonWriter, Item item, boolean lowercaseItems)
throws NotesException, IOException, ServiceException {
writeItem(jsonWriter, item,
lowercaseItems ? item.getName().toLowerCase() : item.getName());
}
Set<String> writtenMimeItems = null;
Set<String> writtenRichTextItems = null;
protected void writeItem(JsonWriter jsonWriter, Item item, String propName)
throws NotesException, IOException, ServiceException {
String itemName = item.getName();
int itemType = item.getType();
if (itemType == Item.OTHEROBJECT) {
// Skip Other Object Types
}
else if (itemType == Item.ATTACHMENT) {
// Skip Attachment Types
}
else if (itemType == Item.NOTELINKS) {
// Skip Note Links Types
}
else if (itemType == Item.SIGNATURE) {
// Skip Signature Types
}
else if (itemType == Item.RICHTEXT) {
if (writtenRichTextItems == null) {
writtenRichTextItems = new HashSet<String>();
}
if (!writtenRichTextItems.contains(itemName)) {
writtenRichTextItems.add(itemName);
writeRichTextItem(jsonWriter, item, propName);
}
}
else if (itemType == Item.MIME_PART) {
if (writtenMimeItems == null) {
writtenMimeItems = new HashSet<String>();
}
if (!writtenMimeItems.contains(itemName)) {
writtenMimeItems.add(itemName);
writeRichTextItem(jsonWriter, item, propName);
}
}
else {
Vector<?> values = item.getValues();
if (values != null && values.size() != 0) {
if (values.size() == 1) {
writeProperty(jsonWriter, propName, values.get(0));
} else {
writeProperty(jsonWriter, propName, values);
}
}
}
}
protected void writeRichTextItem(JsonWriter jsonWriter, Item item, String propName) throws IOException, NotesException, ServiceException {
if (StringUtil.isNotEmpty(rtType) && rtType.contentEquals(TYPE_RICHTEXT)) {
writeItemAsHtml(jsonWriter, item, propName);
}
else {
writeItemAsMime(jsonWriter, item, propName);
}
}
protected void writeItemAsMime(JsonWriter jsonWriter, Item item, String propName) throws IOException, NotesException, ServiceException {
MimeEntityHelper helper = null;
String itemName = item.getName();
jsonWriter.startProperty(propName);
jsonWriter.startObject();
writeProperty(jsonWriter, ATTR_TYPE, TYPE_MULTIPART);
jsonWriter.startProperty(ATTR_CONTENT);
try {
List<JsonMimeEntityAdapter> adapters = new ArrayList<JsonMimeEntityAdapter>();
helper = new MimeEntityHelper(document, itemName);
MIMEEntity entity = helper.getFirstMimeEntity(true);
if ( entity != null ) {
JsonMimeEntityAdapter.addEntityAdapter(adapters, entity);
}
jsonWriter.outLiteral(adapters);
}
catch (JsonException e) {
throw new ServiceException(e);
}
finally {
if ( helper != null ) {
helper.recycle();
}
jsonWriter.endProperty();
jsonWriter.endObject();
jsonWriter.endProperty();
}
}
protected void writeItemAsHtml(JsonWriter jsonWriter, Item item, String propName) throws IOException, NotesException {
DominoUtils.HtmlConverterWrapper converter = null;
String itemName = item.getName();
jsonWriter.startProperty(propName);
jsonWriter.startObject();
try {
converter = new DominoUtils.HtmlConverterWrapper();
writeProperty(jsonWriter, ATTR_TYPE, TYPE_RICHTEXT);
writeProperty(jsonWriter, ATTR_CONTENTTYPE, CONTENTTYPE_TEXT_HTML);
// Convert item to HTML.
converter.convertItem(item.getParent(), itemName);
String htmlContent = converter.getConverterText();
Vector<String> attachments = converter.getReferneceUrls();
writeHtmlAttachmentReference(jsonWriter, htmlContent, attachments);
} finally {
jsonWriter.endObject();
jsonWriter.endProperty();
if (converter != null) {
converter.recycle();
}
}
}
private void writeHtmlAttachmentReference(JsonWriter jsonWriter, String htmlContent, Vector<String> attachments) throws IOException {
if (StringUtil.isEmpty(htmlContent) && attachments.isEmpty()) {
return;
}
String basePathUri = ""; // $NON-NLS-1$
if (StringUtil.isNotEmpty(baseUri) && StringUtil.isNotEmpty(htmlContent)) {
// SPR# DDEY9EYLC2: When it's a relative URL, leave basePathUri empty.
if ( !baseUri.startsWith("/") ) {
basePathUri = baseUri.substring(0, baseUri.indexOf('/', baseUri.indexOf("//") + 2));// $NON-NLS-1$
for (String attachment: attachments) {
htmlContent = htmlContent.replace(attachment, basePathUri + attachment);
}
}
}
if (StringUtil.isNotEmpty(htmlContent)) {
writeProperty(jsonWriter, ATTR_DATA, htmlContent);
}
if (!attachments.isEmpty()) {
jsonWriter.startProperty(ATTR_ATTACHMENTS);
jsonWriter.startArray();
for (String attachment: attachments) {
jsonWriter.startArrayItem();
jsonWriter.startObject();
writeProperty(jsonWriter, RestServiceConstants.ATTR_HREF, basePathUri + attachment);
jsonWriter.endObject();
jsonWriter.endArrayItem();
}
jsonWriter.endArray();
jsonWriter.endProperty();
}
}
protected void writeProperty(JsonWriter jsonWriter, String propName, Vector<?> propValues) throws IOException {
Object value = null;
if (propValues != null && propValues.size() > 0) {
value = propValues.get(0);
}
else {
return;
}
if(value instanceof DateTime && strongType) {
jsonWriter.startProperty(propName);
jsonWriter.startObject();
try {
if (propValues.size() <= 1) {
writeDominoProperty(jsonWriter, ATTR_DATA, propValues.get(0));
} else {
writeDominoProperty(jsonWriter, ATTR_DATA, propValues);
}
writeProperty(jsonWriter, ATTR_TYPE, TYPE_DATETIME);
} finally {
jsonWriter.endObject();
jsonWriter.endProperty();
}
}
else {
if (propValues.size() <= 1) {
writeDominoProperty(jsonWriter, propName, propValues.get(0));
} else {
writeDominoProperty(jsonWriter, propName, propValues);
}
}
}
protected void writeProperty(JsonWriter jsonWriter, String propName, DateTime propValue) throws IOException {
if(strongType) {
jsonWriter.startProperty(propName);
jsonWriter.startObject();
try {
writeDominoProperty(jsonWriter, ATTR_DATA, propValue);
writeProperty(jsonWriter, ATTR_TYPE, TYPE_DATETIME);
} finally {
jsonWriter.endObject();
jsonWriter.endProperty();
}
}
else {
writeDominoProperty(jsonWriter, propName, propValue);
}
}
protected void writeProperty(JsonWriter jsonWriter, String propName, Object propValue) throws IOException {
if (propValue instanceof DateTime) {
writeProperty(jsonWriter, propName, (DateTime)propValue);
}
else if (propValue instanceof Vector) {
writeProperty(jsonWriter, propName, (Vector<?>)propValue);
}
else {
writeDominoProperty(jsonWriter, propName, propValue);
}
}
/**
* Update Notes Items in a Notes Document.
* Called by Document Service and Document Resource for:
* POST PUT PATCH Requests.
*
* @param items
* @param put
* @throws NotesException
* @throws ServiceException
*/
public void updateFields(JsonJavaObject items, boolean put) throws NotesException, ServiceException {
Form form = null;
if (document.hasItem(ITEM_FORM)) {
String formName = document.getItemValueString(ITEM_FORM);
form = document.getParentDatabase().getForm(formName);
}
// Create a list of Notes items.
Set<String> notesItems = null;
if (put) {
notesItems = new HashSet<String> ();
@SuppressWarnings("unchecked") // $NON-NLS-1$
Vector<Item> nItems = document.getItems();
for (Item item: nItems) {
//Item item = (Item) nItems.get(i);
String itemName = item.getName();
if (itemName.charAt(0) != '$' && !itemName.equalsIgnoreCase(ITEM_FORM)) {
notesItems.add(itemName);
}
}
}
// Processs items and remove the item from list if updated.
for(Iterator<String> it = items.getJsonProperties(); it.hasNext(); ) {
String itemName = it.next();
if (itemName != null) {
Object value = items.get(itemName);
if (itemName.charAt(0) != '$' && itemName.charAt(0) != '@' && !itemName.equalsIgnoreCase(ITEM_FORM)) {
updateField(form, itemName, value);
if (put) {
notesItems.remove(itemName);
}
}
}
}
// Remove the item if not updated.
if (put) {
for (String itemName : notesItems) {
document.removeItem(itemName);
}
}
}
protected void updateField(Form form, String itemName, Object value)
throws NotesException, ServiceException {
if (value instanceof JsonJavaObject) {
String type = (String)((JsonJavaObject)value).get(ATTR_TYPE);
if (type == null) {
// Backward compatible with earlier version we may want to change.
//updateRichText(itemName, value);
}
else if (type.equalsIgnoreCase(TYPE_DATETIME)) {
Object data = ((JsonJavaObject)value).get(ATTR_DATA);
if (data instanceof List) {
updateDateTimeList(itemName, (List<?>)data);
}
else {
updateDateTime(itemName, data);
}
}
else if (type.equalsIgnoreCase(TYPE_RICHTEXT)) {
updateRichText(itemName, (JsonJavaObject)value);
}
else if (type.equalsIgnoreCase(TYPE_MULTIPART)) {
try {
updateMimePart(itemName, (JsonJavaObject)value);
}
catch (JsonException e) {
throw new ServiceException(e);
}
}
}
else if (value instanceof List) {
//Vector<?> vector = new Vector((List)value);
//document.replaceItemValue(itemName, vector);
replaceItemValueList(form, itemName, (List<?>)value);
}
else {
//document.replaceItemValue(itemName, value);
replaceItemValue(form, itemName, value);
}
}
private void replaceItemValue(Form form, String itemName, Object value)
throws NotesException {
if (form != null) {
int type = form.getFieldType(itemName);
if (type == Item.DATETIMES) {
updateDateTime(itemName, value);
return;
}
}
document.replaceItemValue(itemName, value);
}
private void replaceItemValueList(Form form, String itemName, List<?> list)
throws NotesException {
if (form != null) {
int type = form.getFieldType(itemName);
if (type == Item.DATETIMES || type == 1025) {
updateDateTimeList(itemName, list);
return;
}
}
Vector<?> vector = new Vector<Object>((List<?>)list);
document.replaceItemValue(itemName, vector);
}
private DateTime toDateTime(Object value) throws NotesException {
DateTime datetime = null;
if ( value instanceof String ) {
// SPR# DDEY9SRL6C: If possible, parse to Java Date. This approach
// gives the same result regardless of regional settings in the OS.
SimpleDateFormat formatter = null;
if ( ((String)value).length() == DATETIME_LENGTH && ((String)value).endsWith("Z") ) {
formatter = DATETIME_FORMAT;
}
// TODO: Ideally, we should parse date-only values (e.g. "2015-02-03") in Java too.
// However, the result of parsing such a value is different in Notes. In Notes
// it truly is a date without a time. In Java the time defaults to midnight UTC.
// For now, rely on the Notes parser -- even though regional settings may vary the result.
if ( formatter != null ) {
try {
value = formatter.parse((String)value);
}
catch (Throwable t) {
// Ignore parser exceptions and fall through
// to Notes parser below
}
}
}
if (value instanceof Date){
datetime = document.getParentDatabase().getParent().createDateTime((Date)value);
}
else if (value instanceof String){
String dtString = (String)value;
if (dtString.endsWith("Z")) { // $NON-NLS-1$
dtString = dtString.substring(0, dtString.lastIndexOf('Z')) + " GMT"; // $NON-NLS-1$ // $NON-NLS-2$
}
datetime = document.getParentDatabase().getParent().createDateTime(dtString);
}
return datetime;
}
private void updateDateTime(String itemName, Object value)
throws NotesException {
DateTime datetime = toDateTime(value);
if (datetime != null) {
document.replaceItemValue(itemName, datetime);
datetime.recycle();
datetime = null;
}
}
private void updateDateTimeList(String itemName, List<?> list)
throws NotesException {
Vector<DateTime> datetimes = new Vector<DateTime>();
for(Object value: list) {
DateTime datetime = toDateTime(value);
datetimes.add(datetime);
}
if (datetimes != null) {
document.replaceItemValue(itemName, datetimes);
for (DateTime datetime: datetimes) {
datetime.recycle();
datetimes = null;
}
}
}
private void updateRichText(String itemName, Object value)
throws NotesException, ServiceException {
MIMEEntity mime = null;
Object attachmentObject = (Object)((JsonJavaObject)value).get(ATTR_ATTACHMENTS);
// If the request contains any references to attachments throw an exception.
if (attachmentObject != null){
@SuppressWarnings("unchecked") // $NON-NLS-1$
ArrayList<JsonJavaObject> jsonObjects = (ArrayList<JsonJavaObject>) attachmentObject;
if (!jsonObjects.isEmpty()) {
throw new ServiceException(null, msgUpdatingEmbeddedObjectsNotSupported());
}
}
if (document.hasItem(itemName)) {
Item item = document.getFirstItem(itemName);
if (item.getType() == Item.MIME_PART) {
MIMEEntity mimeEntity = document.getMIMEEntity(itemName);
MIMEEntity mChild = mimeEntity.getFirstChildEntity();
while (mChild != null) {
MIMEHeader mimeHeader = mChild.getNthHeader(HEADER_CONTENT_TYPE);
// Check Content-Type header for embedded objects.
if (mimeHeader != null) {
String contentType = mimeHeader.getHeaderValAndParams();
if (StringUtil.isNotEmpty(contentType) && contentType.toLowerCase().contains(" name=\"")) { // $NON-NLS-1$
mimeEntity.recycle();
throw new ServiceException(null, msgUpdatingEmbeddedObjectsNotSupported());
}
}
// Check Content-Disposition header for embedded objects.
mimeHeader = mChild.getNthHeader(HEADER_CONTENT_CONTENT_DISPOSITION);
if (mimeHeader != null) {
String contentDisposition = mimeHeader.getHeaderValAndParams();
if (StringUtil.isNotEmpty(contentDisposition) && contentDisposition.toLowerCase().contains(" filename=\"")) { // $NON-NLS-1$
mimeEntity.recycle();
throw new ServiceException(null, msgUpdatingEmbeddedObjectsNotSupported());
}
}
MIMEEntity mChild2 = mChild.getFirstChildEntity();
if (mChild2 == null) {
mChild2 = mChild.getNextSibling();
if (mChild2 == null) {
mChild2 = mChild.getParentEntity();
if (mChild2 != null)
mChild2 = mChild2.getNextSibling();
}
}
mChild.recycle();
mChild = mChild2;
}
mimeEntity.remove();
mimeEntity.recycle();
document.closeMIMEEntities(false, itemName);
}
if (item.getType() == Item.RICHTEXT) {
RichTextItem rtItem = (RichTextItem)item;
if (!rtItem.getEmbeddedObjects().isEmpty()) {
throw new ServiceException(null, msgUpdatingEmbeddedObjectsNotSupported());
}
}
document.removeItem(itemName);
mime = document.createMIMEEntity(itemName);
}
else {
mime = document.createMIMEEntity(itemName);
}
if (mime != null) {
String contentType = (String) ((JsonJavaObject)value).get(ATTR_CONTENTTYPE);
// For now we treat everything as text/html.
if (StringUtil.isEmpty(contentType)) {
contentType = CONTENTTYPE_TEXT_HTML;
}
String data = (String) ((JsonJavaObject)value).get(ATTR_DATA);
if (StringUtil.isEmpty(data)) {
// If the data is empty the call to closeMIMEEntities throws and exception.
data = " "; // $NON-NLS-1$
}
lotus.domino.Session session = document.getParentDatabase().getParent();
lotus.domino.Stream stream = session.createStream();
stream.writeText(data);
// TODO: Add support for other encodings.
MIMEEntity childEntity = mime.createChildEntity();
childEntity.setContentFromText(stream, contentType, lotus.domino.MIMEEntity.ENC_NONE);
stream.close();
stream.recycle();
document.closeMIMEEntities(true, itemName);
mime.recycle();
}
else {
throw new NullPointerException();
}
}
/**
* @return
*/
private String msgUpdatingEmbeddedObjectsNotSupported() {
// extracted to a method so it is only translated once,
// not re-translated for every occurrance
return "Updating embedded objects is not supported.";// $NLX-JsonDocumentContent.Updatingembeddedobjectsisnotsuppo-1$
}
private void updateMimePart(String itemName, JsonJavaObject jsonObject) throws NotesException, JsonException {
if ( document.hasItem(itemName) ) {
Item item = document.getFirstItem(itemName);
if ( item.getType() == Item.MIME_PART ) {
// SPR #JJVX8RGJZG: When updating _existing_ MIME parts, we were
// leaving old attachments around. The fix is to explicitly remove
// the parts first.
MIMEEntity entity = item.getMIMEEntity();
entity.remove();
document.closeMIMEEntities(true, itemName);
}
}
Object jsonMime = jsonObject.get(ATTR_CONTENT);
List<JsonJavaObject> parts = (List<JsonJavaObject>)jsonMime;
ParserContext context = new ParserContext(document, itemName);
for ( int i = 0; i < parts.size(); i++ ) {
JsonJavaObject obj = parts.get(i);
boolean lastEntity = false;
if ( (i+1) == parts.size() ) {
lastEntity = true;
}
JsonMimeEntityAdapter adapter = new JsonMimeEntityAdapter(context, obj);
context.setCurrentEntityAdapter(adapter);
adapter.flushJsonProperties(lastEntity);
}
}
private static SimpleDateFormat getDateTimeFormatter() {
TimeZone tz = TimeZone.getTimeZone("UTC"); // $NON-NLS-1$
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); //$NON-NLS-1$
formatter.setTimeZone(tz);
return formatter;
}
}