/******************************************************************************* * Copyright © 2006, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.javart.util; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import org.eclipse.edt.javart.AnyBoxedObject; import org.eclipse.edt.javart.ControlFlow; import org.eclipse.edt.javart.FatalProblem; import org.eclipse.edt.javart.RunUnit; import org.eclipse.edt.javart.Runtime; import org.eclipse.edt.javart.messages.Message; import org.eclipse.edt.runtime.java.eglx.lang.EAny; import eglx.java.JavaObjectException; import eglx.lang.AnyException; import eglx.lang.InvalidIndexException; import eglx.lang.NullValueException; /** * JavartUtil contains some helpful utility functions. It's not meant to be * instantiated; all the methods are static. */ public class JavartUtil { /** * The system line separator (CRLF on Windows). */ public static final String LINE_SEPARATOR = System.getProperty( "line.separator" ); /** * A GregorianCalendar. */ private static GregorianCalendar gregorianCalendar; /** * The constructor. It's private to prevent instantiation. */ private JavartUtil() { // Nothing to do } /** * Returns a GregorianCalendar that can be used for time and date functions. * * @return a GregorianCalendar. */ public static GregorianCalendar getCalendar() { if ( gregorianCalendar == null ) { gregorianCalendar = new GregorianCalendar(); } return gregorianCalendar; } /** * Returns the current time in "HH:MM:SS" format. A 24-hour clock is used, * so 1pm is "13:00:00". * * @return The time */ public static String getCurrentTime() { // Get the current time. GregorianCalendar calendar = getCalendar(); calendar.setTime( new Date() ); int hour = calendar.get( Calendar.HOUR_OF_DAY ); int minute = calendar.get( Calendar.MINUTE ); int second = calendar.get( Calendar.SECOND ); // Make sure each part has two digits. StringBuilder time = new StringBuilder( 8 ); if ( hour < 10 ) { time.append( '0' ); } time.append( hour ); time.append( ':' ); if ( minute < 10 ) { time.append( '0' ); } time.append( minute ); time.append( ':' ); if ( second < 10 ) { time.append( '0' ); } time.append( second ); // Concatenate the parts to get the result. return time.toString(); } /** * Returns a string containing the Object's type in EGL. * * @param object the Object. */ public static String getEglType( Object object ) { if ( object instanceof EAny ) { return ((EAny)object).ezeTypeSignature(); } else { return object.getClass().getName(); } } /** * Returns the name of a class minus its package. * * @param fullName the class name to use. * @return <code>fullName</code> minus its package. */ public static String removePackageName( String fullName ) { int index = fullName.lastIndexOf( '.' ); if ( index == -1 ) { return fullName; } return fullName.substring( index + 1 ); } /** * Checks the start and end indices for a substring access, and throws an * exception with ID = Message.INVALID_SUBSTRING_INDEX if they are invalid. * * @param startIndex The start index. * @param endIndex The end index. * @param maxlen The maximum length of the item being substringed. * @throws AnyException */ public static void checkSubstringIndices( int startIndex, int endIndex, int maxlen ) throws AnyException { if ( startIndex < 1 || startIndex > maxlen ) { // startIndex is bad. InvalidIndexException ex = new InvalidIndexException(); ex.index = startIndex; throw ex.fillInMessage( Message.INVALID_SUBSTRING_INDEX, startIndex, endIndex ); } else if ( endIndex < startIndex || endIndex < 1 || endIndex > maxlen ) { // endIndex is bad. InvalidIndexException ex = new InvalidIndexException(); ex.index = endIndex; throw ex.fillInMessage( Message.INVALID_SUBSTRING_INDEX, startIndex, endIndex ); } } /** * Builds an error message with no inserts. If tracing is on, the message will * be written to the trace. If logging is on, it will be written to the log. * * @param id the message ID. * @return the error message. */ public static String errorMessage( String id ) { RunUnit ru = Runtime.getRunUnit(); String message = ru.getLocalizedText().getMessage( id ); // Write the message to the trace. if ( ru.getTrace().traceIsOn() ) { ru.getTrace().put( message ); } return message; } /** * Builds an error message. If tracing is on, it will be written to the * trace. If logging is on, it will be written to the log. * * @param id the message ID. * @param inserts the message inserts. * @return the error message. */ public static String errorMessage( String id, Object... inserts ) { RunUnit ru = Runtime.getRunUnit(); String message = ru.getLocalizedText().getMessage( id, inserts ); // Write the message to the trace. if ( ru.getTrace().traceIsOn() ) { ru.getTrace().put( message ); } return message; } /** * This is called by generated code to ensure a try statement doesn't hide * an exception that can't be handled in EGL. If the Exception that was * caught can't be ignored, it is re-thrown. Otherwise nothing happens. * * @param caught the Exception that was caught. * @throws the Exception, if it can't be ignored. */ public static void checkHandleable( Exception caught ) throws RuntimeException { if ( caught instanceof FatalProblem || caught instanceof ControlFlow ) { throw (RuntimeException)caught; } } /** * utility to check to see if an object is null and if it is, then throw * a NullValueException, otherwise return the object */ public static <T extends Object> T checkNullable(T o) throws NullValueException { if (o == null || (o instanceof AnyBoxedObject && ((AnyBoxedObject<?>) o).ezeUnbox() == null)) { NullValueException nvx = new NullValueException(); throw nvx.fillInMessage( Message.NULL_NOT_ALLOWED ); } return o; } /** * utility to check to see if an index is out of bounds and if it is, then throw * a InvalidIndexException, otherwise return the index */ public static int checkIndex(int index, List<?> list) throws InvalidIndexException { if (list == null) { NullValueException nvx = new NullValueException(); throw nvx.fillInMessage( Message.NULL_NOT_ALLOWED ); } if (index < 0 || index >= list.size()) { InvalidIndexException iix = new InvalidIndexException(); iix.index = index; throw iix.fillInMessage( Message.LIST_INDEX_OUT_OF_BOUNDS, index, list.size() ); } return index; } /** * Returns an AnyException for the given Throwable. If the Throwable is * already an AnyException, it is returned. In all other cases we'll return * a JavaObjectException. */ public static AnyException makeEglException( Throwable ex ) { if ( ex instanceof AnyException ) { return (AnyException)ex; } String msg = ex.getMessage(); String className = ex.getClass().getName(); if ( msg == null || msg.length() == 0 ) { msg = className; } JavaObjectException jox = new JavaObjectException(); jox.exceptionType = className; jox.initCause( ex ); return jox.fillInMessage( Message.CAUGHT_JAVA_EXCEPTION, msg ); } /** * Returns true if the Exception is a JavaObjectException, or something that * should be represented as a JavaObjectException. */ public static boolean isJavaObjectException( Exception ex ) { return ex instanceof JavaObjectException || !(ex instanceof eglx.lang.AnyException); } /** * Our ExecutorService (thread pool). */ private static ExecutorService threadPool; /** * A class that ensures the threads in our pool are daemons. */ private static class EGLThreadFactory implements ThreadFactory { public Thread newThread( Runnable r ) { Thread t = new Thread( r ); t.setDaemon( true ); return t; } } /** * @return the ExecutorService. */ public synchronized static ExecutorService getThreadPool() { if ( threadPool == null ) { threadPool = Executors.newCachedThreadPool( new EGLThreadFactory() ); } return threadPool; } }