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

es.ree.eemws.kit.cmd.list.Main Maven / Gradle / Ivy

Go to download

Client implementation of IEC 62325-504 technical specification. eemws-kit includes command line utilities to invoke the eem web services, as well as several GUI applications (browser, editor, ...)

The newest version!
/*
 * Copyright 2024 Redeia.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 *  by the Free Software Foundation, version 3 of the license.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTIBIILTY or FITNESS FOR A PARTICULAR PURPOSE. See GNU Lesser General
 * Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program. If not, see
 * http://www.gnu.org/licenses/.
 *
 * Any redistribution and/or modification of this program has to make
 * reference to Redeia as the copyright owner of the program.
 */
package es.ree.eemws.kit.cmd.list;

import java.net.MalformedURLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import es.ree.eemws.client.list.ListMessages;
import es.ree.eemws.client.list.MessageListEntry;
import es.ree.eemws.core.utils.config.ConfigException;
import es.ree.eemws.core.utils.error.EnumErrorCatalog;
import es.ree.eemws.core.utils.iec61968100.EnumFilterElement;
import es.ree.eemws.core.utils.iec61968100.EnumIntervalTimeType;
import es.ree.eemws.core.utils.iec61968100.MessageUtil;
import es.ree.eemws.core.utils.operations.list.ListOperationException;
import es.ree.eemws.kit.cmd.MessageCatalog;
import es.ree.eemws.kit.cmd.ParentMain;

/**
 * Lists messages using the command line.
 *
 * @author Redeia.
 * @version 2.1 01/01/2024
 */

public final class Main extends ParentMain {

	/** Log messages. */
	private static final Logger LOGGER = Logger.getLogger("list"); //$NON-NLS-1$

	/** Sets text for parameter code. */
	private static final String PARAMETER_CODE = MessageCatalog.PARAMETER_CODE.getMessage();

	/** Sets text for parameter startTime. */
	private static final String PARAMETER_START_TIME = MessageCatalog.PARAMETER_START_TIME.getMessage();

	/** Sets text for parameter endTime. */
	private static final String PARAMETER_END_TIME = MessageCatalog.PARAMETER_END_TIME.getMessage();

	/** Sets text for parameter intervalTime. */
	private static final String LIST_PARAMETER_INTERVAL_TYPE = ListMessageCatalog.LIST_PARAMETER_INTERVAL_TYPE
	        .getMessage();

	/** Sets text for parameter msgId. */
	private static final String PARAMETER_MSG_ID = MessageCatalog.PARAMETER_MSG_ID.getMessage();

	/** Sets text for parameter msgType. */
	private static final String LIST_PARAMETER_MSG_TYPE = ListMessageCatalog.LIST_PARAMETER_MSG_TYPE.getMessage();

	/** Sets text for parameter owner. */
	private static final String LIST_PARAMETER_MSG_OWNER = ListMessageCatalog.LIST_PARAMETER_MSG_OWNER.getMessage();

	/** Sets text for parameter url. */
	private static final String PARAMETER_URL = MessageCatalog.PARAMETER_URL.getMessage();

	/** Format pattern for code. */
	private static final String CODE_FORMAT = "%20s"; //$NON-NLS-1$

	/** Format pattern for MessageIdentification.Version. */
	private static final String MESSAGE_IDENTIFICATION_VERSION_FORMAT = "%40s"; //$NON-NLS-1$

	/** Format pattern for Status. */
	private static final String STATUS_FORMAT = "%6s"; //$NON-NLS-1$

	/** Format pattern for Message Type. */
	private static final String MSG_TYPE_FORMAT = "%50s"; //$NON-NLS-1$

	/** Format pattern for Owner. */
	private static final String OWNER_FORMAT = "%20s"; //$NON-NLS-1$

	/** Date format with minutes. */
	private static final String DATE_FORMAT_MINUTES = "dd-MM-yyyy HH:mm"; //$NON-NLS-1$

	/** Date format with seconds. */
	private static final String DATE_FORMAT_SECONDS = "dd-MM-yyyy HH:mm:ss"; //$NON-NLS-1$

	/** Format pattern for date. */
	private static final String DATE_FORMAT = "%" + DATE_FORMAT_MINUTES.length() + "s"; //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * Main. Executes the list command.
	 *
	 * @param args command line arguments.
	 */
	public static void main(final String[] args) {

		var urlEndPoint = ""; //$NON-NLS-1$

		try {

			/* Reads command line parameters, store its values. */
			List arguments = new ArrayList<>(Arrays.asList(args));

			/* If the list has duplicates must stop the execution. */
			var dup = findDuplicates(arguments, PARAMETER_START_TIME, PARAMETER_END_TIME, LIST_PARAMETER_INTERVAL_TYPE,
			        PARAMETER_CODE, PARAMETER_MSG_ID, LIST_PARAMETER_MSG_TYPE, LIST_PARAMETER_MSG_OWNER, PARAMETER_URL);

			if (dup != null) {
				throw new ListOperationException(EnumErrorCatalog.LST_010,
				        MessageCatalog.PARAMETER_REPEATED.getMessage(dup));
			}

			var startTime = readParameter(arguments, PARAMETER_START_TIME);
			var endTime = readParameter(arguments, PARAMETER_END_TIME);
			var intervalType = readParameter(arguments, LIST_PARAMETER_INTERVAL_TYPE);
			var code = readParameter(arguments, PARAMETER_CODE);
			var msgId = readParameter(arguments, PARAMETER_MSG_ID);
			var msgType = readParameter(arguments, LIST_PARAMETER_MSG_TYPE);
			var owner = readParameter(arguments, LIST_PARAMETER_MSG_OWNER);
			urlEndPoint = readParameter(arguments, PARAMETER_URL);

			/*
			 * If the list is not empty means that user has put at least one "unknown" or
			 * repeated parameter. Show only first.
			 */
			if (!arguments.isEmpty()) {
				throw new ListOperationException(EnumErrorCatalog.LST_011, arguments.get(0));
			}

			/*
			 * Creates a request with all the parameters. Do not make any validation here.
			 */
			Map msgOptions = new HashMap<>();

			if (code != null) {
				msgOptions.put(EnumFilterElement.CODE.toString(), code);
			}

			if (startTime != null) {
				var sdf = new SimpleDateFormat(DATE_FORMAT_PATTERN);

				Date dateStartTime = null;
				try {
					dateStartTime = sdf.parse(startTime);
					msgOptions.put(EnumFilterElement.START_TIME.toString(), MessageUtil.formatDate(dateStartTime));
				} catch (ParseException e) {
					throw new ListOperationException(EnumErrorCatalog.LST_010,
					        ListMessageCatalog.LIST_INVALID_DATE_FORMAT.getMessage(startTime, DATE_FORMAT_PATTERN));
				}

				/* By default, endTime = end of the day of startTime */
				Date dateEndTime;
				if (endTime == null) {
					var cal = Calendar.getInstance();
					cal.setTime(dateStartTime);
					cal.add(Calendar.DAY_OF_MONTH, 1);
					cal.add(Calendar.SECOND, -1);
					dateEndTime = cal.getTime();
				} else {
					try {
						dateEndTime = sdf.parse(endTime);
					} catch (ParseException e) {
						throw new ListOperationException(EnumErrorCatalog.LST_010,
						        ListMessageCatalog.LIST_INVALID_DATE_FORMAT.getMessage(endTime, DATE_FORMAT_PATTERN));
					}
				}

				msgOptions.put(EnumFilterElement.END_TIME.toString(), MessageUtil.formatDate(dateEndTime));
			}

			if (intervalType != null) {
				msgOptions.put(EnumFilterElement.INTERVAL_TYPE.toString(), intervalType);
			}

			if (msgId != null) {
				msgOptions.put(EnumFilterElement.MESSAGE_IDENTIFICATION.toString(), msgId);
			}

			if (msgType != null) {
				msgOptions.put(EnumFilterElement.MESSAGE_TYPE.toString(), msgType);
			}

			if (owner != null) {
				msgOptions.put(EnumFilterElement.OWNER.toString(), owner);
			}

			/* Sets the url, if no url is provided by arguments, use the one configured. */
			urlEndPoint = setConfig(urlEndPoint);

			/* Creates and set up a get object. */
			var list = new ListMessages();
			list.setEndPoint(urlEndPoint);

			/*
			 * Send the request (list operation will validate at this point the parameters)
			 */
			var init = System.currentTimeMillis();
			showResults(list.list(msgOptions));
			var end = System.currentTimeMillis();

			/* Writes performance values on screen. */
			if (LOGGER.isLoggable(Level.INFO)) {
				LOGGER.info(MessageCatalog.EXECUTION_TIME.getMessage(getPerformance(init, end)));
			}

		} catch (ListOperationException e) {

			var code = e.getCode();

			if (code.equals(EnumErrorCatalog.HAND_010.name())) {

				LOGGER.log(Level.SEVERE,
				        String.format("%s : %s %s", e.getCode(), e.getMessage(), e.getCause().getMessage()));

			} else {

				LOGGER.log(Level.SEVERE, String.format("%s : %s", e.getCode(), e.getMessage()), e.getCause());

				/* Bad parameters? show usage! */
				if (code.equals(EnumErrorCatalog.LST_010.name()) || code.equals(EnumErrorCatalog.LST_005.name())
				        || code.equals(EnumErrorCatalog.LST_011.name())) {

					LOGGER.info(ListMessageCatalog.LIST_USAGE.getMessage(PARAMETER_CODE, PARAMETER_START_TIME,
					        PARAMETER_END_TIME, LIST_PARAMETER_INTERVAL_TYPE, PARAMETER_MSG_ID, LIST_PARAMETER_MSG_TYPE,
					        LIST_PARAMETER_MSG_OWNER, PARAMETER_URL, new Date(),
					        EnumIntervalTimeType.APPLICATION.toString(), EnumIntervalTimeType.SERVER.toString()));
				}
			}

			/* Show full stack trace in debug. */
			LOGGER.log(Level.FINE, "", e); //$NON-NLS-1$

		} catch (MalformedURLException e) {

			LOGGER.severe(MessageCatalog.INVALID_URL.getMessage(urlEndPoint));

		} catch (ConfigException e) {

			LOGGER.severe(MessageCatalog.INVALID_CONFIGURATION.getMessage(e.getMessage()));

			/* Shows stack trace only for debug. Don't bother the user with this details. */
			LOGGER.log(Level.FINE, MessageCatalog.INVALID_CONFIGURATION.getMessage(e.getMessage()), e);

		}
	}

	/**
	 * This method shows the results.
	 *
	 * @param response List of the message listings.
	 * @throws ClientException If the server returns an invalid message list entry.
	 */
	private static void showResults(final List response) {

		if (response != null && !response.isEmpty()) {

			var sdf = new SimpleDateFormat(DATE_FORMAT_MINUTES);

			var sdfTimestamp = new SimpleDateFormat(DATE_FORMAT_SECONDS);

			var error = new StringBuilder();
			var sb = new StringBuilder();
			sb.append(ListMessageCatalog.LIST_OUTPUT_HEADER.getMessage());

			var numMessages = 0;
			long maxCode = -1;

			for (MessageListEntry msgData : response) {

				var bufferPos = sb.length();

				try {

					sb.append("\n"); //$NON-NLS-1$
					sb.append(String.format(CODE_FORMAT, msgData.getCode().toString()));
					sb.append(" "); //$NON-NLS-1$

					if (msgData.getVersion() == null) { // Version is optional
						sb.append(String.format(MESSAGE_IDENTIFICATION_VERSION_FORMAT,
						        msgData.getMessageIdentification()));
					} else {
						sb.append(String.format(MESSAGE_IDENTIFICATION_VERSION_FORMAT,
						        msgData.getMessageIdentification() + "." + msgData.getVersion())); //$NON-NLS-1$
					}

					sb.append(" "); //$NON-NLS-1$

					if (msgData.getStatus() == null) { // Status is optional
						sb.append(String.format(STATUS_FORMAT, "")); //$NON-NLS-1$
					} else {
						sb.append(String.format(STATUS_FORMAT, msgData.getStatus()));
					}

					sb.append(" "); //$NON-NLS-1$
					sb.append(sdf.format(msgData.getApplicationStartTime().getTime()));
					sb.append(" - "); //$NON-NLS-1$

					if (msgData.getApplicationEndTime() == null) { // End date is optional
						sb.append(String.format(DATE_FORMAT, "")); //$NON-NLS-1$
					} else {
						sb.append(sdf.format(msgData.getApplicationEndTime().getTime()));
					}

					sb.append(" "); //$NON-NLS-1$
					sb.append(sdfTimestamp.format(msgData.getServerTimestamp().getTime()));

					sb.append(" "); //$NON-NLS-1$
					sb.append(String.format(MSG_TYPE_FORMAT, msgData.getType()));

					sb.append(" "); //$NON-NLS-1$
					sb.append(String.format(OWNER_FORMAT, msgData.getOwner()));

					numMessages++;
					maxCode = Math.max(msgData.getCode().longValue(), maxCode);

				} catch (NullPointerException npe) {

					/*
					 * Don't stop the loop if the server sends one (or more) non-valid entries. Put
					 * these entries information into a special error buffer.
					 */
					sb.delete(bufferPos, sb.length());

					try {
						msgData.checkMandatoryElements();
					} catch (ListOperationException e) {
						error.append(e.toString());
						error.append("\n"); //$NON-NLS-1$
					}
				}
			}

			sb.append("\n"); //$NON-NLS-1$
			sb.append(numMessages);
			sb.append(" "); //$NON-NLS-1$
			sb.append(ListMessageCatalog.LIST_NUM_OF_MESSAGES.getMessage());
			sb.append(" "); //$NON-NLS-1$
			sb.append(ListMessageCatalog.LIST_MAX_CODE.getMessage(String.valueOf(maxCode)));

			if (LOGGER.isLoggable(Level.INFO)) {
				LOGGER.info(sb.toString());
			}

			if (error.length() > 0 && LOGGER.isLoggable(Level.SEVERE)) {
				LOGGER.severe(error.toString());
			}

		} else if (LOGGER.isLoggable(Level.INFO)) {
			LOGGER.info(ListMessageCatalog.LIST_NO_MESSAGES.getMessage());
		}

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy