All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.simplity.service.ServiceContext Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2015 EXILANT Technologies Private Limited (www.exilant.com)
 * Copyright (c) 2016 simplity.org
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.simplity.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.jms.Session;

import org.simplity.json.JSONWriter;
import org.simplity.kernel.ApplicationError;
import org.simplity.kernel.FormattedMessage;
import org.simplity.kernel.MessageBox;
import org.simplity.kernel.MessageType;
import org.simplity.kernel.Messages;
import org.simplity.kernel.data.CommonData;
import org.simplity.kernel.data.DataSheet;
import org.simplity.kernel.data.FieldsInterface;
import org.simplity.kernel.data.MultiRowsSheet;
import org.simplity.kernel.util.TextUtil;
import org.simplity.kernel.value.Value;
import org.simplity.kernel.value.ValueType;

/**
 * Context is created for an execution of a service. A service execution
 * requires a number of actions to be performed. However, each action is on its
 * own, and does not assume presence of any other action. Of course, it expects
 * that certain data is available, and it's job may be to extract some more
 * data.
 *
 * We use a common (we can call this global for the service) data context for
 * all such action. While a DataScape is good enough data structure, we would
 * like to make use this concept for other design aspects, like accumulating
 * messages and tracking error states etc.. Hence this class extends DataScape.
 *
 * @author simplity.org
 *
 */
public class ServiceContext extends CommonData {

	private final String serviceName;
	private final Value userId;
	private List messages = new ArrayList();
	private int nbrErrors = 0;

	/**
	 * writer that can be used by actions to write directly to the response
	 */
	private ResponseWriter responseWriter;
	/**
	 * jms session associated with this service
	 */
	private Session jmsSession;

	/**
	 * message box
	 */
	private MessageBox messageBox;

	/**
	 * @param serviceName
	 * @param userId
	 */
	public ServiceContext(String serviceName, Value userId) {
		this.userId = userId;
		this.serviceName = serviceName;
	}

	/**
	 * add a message that is associated with a data element in the input data
	 *
	 * @param messageName
	 * @param referredField
	 *            if this is about a specific field, so that client can
	 *            associate this message with a field/column
	 * @param otherReferredField
	 *            if the message has more than one referred field, like from-to
	 *            validation failed
	 * @param referredTable
	 *            if the referred field is actually a column in a table
	 * @param rowNumber
	 *            if table is referred, 1 based.
	 * @param params
	 *            if the message is parameterized, provide values for those
	 *            parameters. $name means name is a field, and the field value
	 *            is to be taken from context
	 * @return type of message that got added
	 */
	public MessageType addValidationMessage(String messageName, String referredField, String otherReferredField,
			String referredTable, int rowNumber, String... params) {
		String[] values = null;
		if (params != null && params.length > 0) {
			values = new String[params.length];
			for (int i = 0; i < values.length; i++) {
				String val = params[i];
				/*
				 * if it is a field name, we get its value
				 */
				String fieldName = TextUtil.getFieldName(val);
				if (fieldName != null) {
					Value v = this.getValue(fieldName);
					if (v != null) {
						val = v.toString();
					}
				}
				values[i] = val;
			}
		}

		FormattedMessage msg = Messages.getMessage(messageName, values);
		if (msg.messageType == MessageType.ERROR) {
			this.nbrErrors++;
		}
		msg.fieldName = referredField;
		msg.relatedFieldName = otherReferredField;
		msg.tableName = referredTable;
		msg.rowNumber = rowNumber;
		this.messages.add(msg);
		return msg.messageType;
	}

	/**
	 * add a message that has no reference to a data element
	 *
	 * @param messageName
	 * @param paramValues
	 *            if the message is parameterized, provide values for those
	 *            parameters
	 * @return type of message that got added
	 */
	public MessageType addMessage(String messageName, String... paramValues) {
		return this.addValidationMessage(messageName, null, null, null, 0, paramValues);
	}

	/**
	 * add row to the messages list, but after checking for error status
	 *
	 * @param messageName
	 * @param messageType
	 * @param messageText
	 * @param referredField
	 * @param otherReferredField
	 * @param referredTable
	 * @param rowNumber
	 */
	public void addMessageRow(String messageName, MessageType messageType, String messageText, String referredField,
			String otherReferredField, String referredTable, int rowNumber) {
		if (messageType == MessageType.ERROR) {
			this.nbrErrors++;
		}
		FormattedMessage msg = new FormattedMessage(messageName, messageType, messageText);
		msg.fieldName = referredField;
		msg.relatedFieldName = otherReferredField;
		msg.tableName = referredTable;
		msg.rowNumber = rowNumber;
		this.messages.add(msg);
	}

	/**
	 * has any one raised an error message?
	 *
	 * @return true if any error message is added. False otherwise
	 */
	public boolean isInError() {
		return this.nbrErrors > 0;
	}

	/**
	 * get all messages
	 *
	 * @return messages
	 */
	public List getMessages() {
		return this.messages;
	}

	/**
	 * get all messages as a DataSheet
	 *
	 * @return messages
	 */
	public DataSheet getMessagesAsDs() {
		String[] columnNames = { "name", "text", "messageType", "fieldName" };
		Collection msgs = this.getMessages();
		int nbr = msgs.size();
		if (nbr == 0) {
			ValueType[] types = { ValueType.TEXT, ValueType.TEXT, ValueType.TEXT, ValueType.TEXT };
			return new MultiRowsSheet(columnNames, types);
		}
		/*
		 * data is by column
		 */
		Value[][] data = new Value[4][nbr];

		int i = 0;
		for (FormattedMessage msg : msgs) {
			data[0][i] = Value.newTextValue(msg.name);
			data[1][i] = Value.newTextValue(msg.text);
			data[2][i] = Value.newTextValue(msg.messageType.name());
			data[3][i] = Value.newTextValue(msg.fieldName);
			i++;
		}

		return new MultiRowsSheet(columnNames, data);

	}

	/**
	 * sreset/remove all messages
	 *
	 */
	public void resetMessages() {
		this.messages.clear();
		this.nbrErrors = 0;
	}

	/**
	 *
	 * @return userId for whom this context is created
	 */
	public Value getUserId() {
		return this.userId;
	}

	/**
	 *
	 * @return service for which this context is created
	 */
	public String getServiceName() {
		return this.serviceName;
	}

	/**
	 * @param dataRow
	 */
	public void copyFrom(FieldsInterface dataRow) {
		for (Entry entry : dataRow.getAllFields()) {
			this.allFields.put(entry.getKey(), entry.getValue());
		}

	}

	/**
	 *
	 * @return set of all sheets that you can iterate over
	 */
	public Set> getAllSheets() {
		return this.allSheets.entrySet();
	}

	/**
	 * @return summary for tracing
	 */
	public String getSummaryInfo() {
		StringBuilder sbf = new StringBuilder("Context has ");
		sbf.append(this.allFields.size()).append(" fields and ").append(this.allSheets.size()).append(" sheets and ")
				.append(this.messages.size()).append(" messages.");
		return sbf.toString();
	}

	/**
	 * add error messages from an accumulated list
	 *
	 * @param errors
	 */
	public void addMessages(List errors) {
		if (errors == null) {
			return;
		}
		for (FormattedMessage msg : errors) {
			this.messages.add(msg);
			if (msg.messageType == MessageType.ERROR) {
				this.nbrErrors++;
			}
		}

	}

	/**
	 *
	 * @param sheetName
	 * @return 0 if sheet does not exist
	 */
	public int nbrRowsInSheet(String sheetName) {
		DataSheet ds = this.getDataSheet(sheetName);
		if (ds == null) {
			return 0;
		}
		return ds.length();
	}

	/**
	 * set a default response writer to the context
	 *
	 * @param writer
	 */
	public void setWriter(ResponseWriter writer) {
		this.responseWriter = writer;

	}

	/**
	 * @return writer, never null
	 */
	public ResponseWriter getWriter() {
		if (this.responseWriter == null) {
			this.setWriter(new JSONWriter());
			this.responseWriter.init();
		}
		return this.responseWriter;

	}

	/**
	 * @param session
	 */
	public void setJmsSession(Session session) {
		this.jmsSession = session;
	}

	/**
	 * @return jms connector associated with this service. never null.
	 * @throws ApplicationError
	 *             in case this service is not associated with a connector
	 */
	public Session getJmsSession() {
		if (this.jmsSession == null) {
			throw new ApplicationError("This service is not set up for a JMS operation.");
		}
		return this.jmsSession;
	}

	/**
	 * @param message
	 */
	public void putMessageInBox(Object message) {
		if (this.messageBox == null) {
			this.messageBox = new MessageBox();
		}
		this.messageBox.setMessage(message);
	}

	/**
	 * @return message, or null if there is none
	 */
	public Object getMessageFromBox() {
		if (this.messageBox == null) {
			return null;
		}
		return this.messageBox.getMessage();
	}

	/**
	 * @param box
	 */
	public void setMessageBox(MessageBox box) {
		this.messageBox = box;
	}

	/**
	 * @return message box, or null if there is none
	 */
	public MessageBox getMessageBox() {
		return this.messageBox;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy