Create classes for the progress monitoring feature.
Change-Id: Iea384ee86b15dbb200abc3e3c807b8fdc56ccb04
Signed-off-by: Heongseok Heo <hyeongseok.heo@samsung.com>
--- /dev/null
+/*
+ * Copyright (C) 2008-2011, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.tizen.core.ide;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+/** ProgressMonitor that batches update events. */
+public abstract class BatchingProgressMonitor implements ProgressMonitor {
+ private static final ScheduledThreadPoolExecutor alarmQueue;
+
+ static final Object alarmQueueKiller;
+
+ static {
+ // To support garbage collection, start our thread but
+ // swap out the thread factory. When our class is GC'd
+ // the alarmQueueKiller will finalize and ask the executor
+ // to shutdown, ending the worker.
+ //
+ int threads = 1;
+ alarmQueue = new ScheduledThreadPoolExecutor(threads,
+ new ThreadFactory() {
+ private final ThreadFactory baseFactory = Executors
+ .defaultThreadFactory();
+
+ public Thread newThread(Runnable taskBody) {
+ Thread thr = baseFactory.newThread(taskBody);
+ thr.setName("JGit-AlarmQueue"); //$NON-NLS-1$
+ thr.setDaemon(true);
+ return thr;
+ }
+ });
+ alarmQueue.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+ alarmQueue.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+ alarmQueue.prestartAllCoreThreads();
+
+ // Now that the threads are running, its critical to swap out
+ // our own thread factory for one that isn't in the ClassLoader.
+ // This allows the class to GC.
+ //
+ alarmQueue.setThreadFactory(Executors.defaultThreadFactory());
+
+ alarmQueueKiller = new Object() {
+ @Override
+ protected void finalize() {
+ alarmQueue.shutdownNow();
+ }
+ };
+ }
+
+ private long delayStartTime;
+
+ private TimeUnit delayStartUnit = TimeUnit.MILLISECONDS;
+
+ private Task task;
+
+ /**
+ * Set an optional delay before the first output.
+ *
+ * @param time
+ * how long to wait before output. If 0 output begins on the
+ * first {@link #update(int)} call.
+ * @param unit
+ * time unit of {@code time}.
+ */
+ public void setDelayStart(long time, TimeUnit unit) {
+ delayStartTime = time;
+ delayStartUnit = unit;
+ }
+
+ public void start(int totalTasks) {
+ // Ignore the number of tasks.
+ }
+
+ public void beginTask(String title, int work) {
+ endTask();
+ task = new Task(title, work);
+ if (delayStartTime != 0)
+ task.delay(delayStartTime, delayStartUnit);
+ }
+
+ public void update(int completed) {
+ if (task != null)
+ task.update(this, completed);
+ }
+
+ public void endTask() {
+ if (task != null) {
+ task.end(this);
+ task = null;
+ }
+ }
+
+ public boolean isCancelled() {
+ return false;
+ }
+
+ /**
+ * Update the progress monitor if the total work isn't known,
+ *
+ * @param taskName
+ * name of the task.
+ * @param workCurr
+ * number of units already completed.
+ */
+ protected abstract void onUpdate(String taskName, int workCurr);
+
+ /**
+ * Finish the progress monitor when the total wasn't known in advance.
+ *
+ * @param taskName
+ * name of the task.
+ * @param workCurr
+ * total number of units processed.
+ */
+ protected abstract void onEndTask(String taskName, int workCurr);
+
+ /**
+ * Update the progress monitor when the total is known in advance.
+ *
+ * @param taskName
+ * name of the task.
+ * @param workCurr
+ * number of units already completed.
+ * @param workTotal
+ * estimated number of units to process.
+ * @param percentDone
+ * {@code workCurr * 100 / workTotal}.
+ */
+ protected abstract void onUpdate(String taskName, int workCurr,
+ int workTotal, int percentDone);
+
+ /**
+ * Finish the progress monitor when the total is known in advance.
+ *
+ * @param taskName
+ * name of the task.
+ * @param workCurr
+ * total number of units processed.
+ * @param workTotal
+ * estimated number of units to process.
+ * @param percentDone
+ * {@code workCurr * 100 / workTotal}.
+ */
+ protected abstract void onEndTask(String taskName, int workCurr,
+ int workTotal, int percentDone);
+
+ private static class Task implements Runnable {
+ /** Title of the current task. */
+ private final String taskName;
+
+ /** Number of work units, or {@link ProgressMonitor#UNKNOWN}. */
+ private final int totalWork;
+
+ /** True when timer expires and output should occur on next update. */
+ private volatile boolean display;
+
+ /** Scheduled timer, supporting cancellation if task ends early. */
+ private Future<?> timerFuture;
+
+ /** True if the task has displayed anything. */
+ private boolean output;
+
+ /** Number of work units already completed. */
+ private int lastWork;
+
+ /** Percentage of {@link #totalWork} that is done. */
+ private int lastPercent;
+
+ Task(String taskName, int totalWork) {
+ this.taskName = taskName;
+ this.totalWork = totalWork;
+ this.display = true;
+ }
+
+ void delay(long time, TimeUnit unit) {
+ display = false;
+ timerFuture = alarmQueue.schedule(this, time, unit);
+ }
+
+ public void run() {
+ display = true;
+ }
+
+ void update(BatchingProgressMonitor pm, int completed) {
+ lastWork += completed;
+
+ if (totalWork == UNKNOWN) {
+ // Only display once per second, as the alarm fires.
+ if (display) {
+ pm.onUpdate(taskName, lastWork);
+ output = true;
+ restartTimer();
+ }
+ } else {
+ // Display once per second or when 1% is done.
+ int currPercent = lastWork * 100 / totalWork;
+ if (display) {
+ pm.onUpdate(taskName, lastWork, totalWork, currPercent);
+ output = true;
+ restartTimer();
+ lastPercent = currPercent;
+ } else if (currPercent != lastPercent) {
+ pm.onUpdate(taskName, lastWork, totalWork, currPercent);
+ output = true;
+ lastPercent = currPercent;
+ }
+ }
+ }
+
+ private void restartTimer() {
+ display = false;
+ timerFuture = alarmQueue.schedule(this, 1, TimeUnit.SECONDS);
+ }
+
+ void end(BatchingProgressMonitor pm) {
+ if (output) {
+ if (totalWork == UNKNOWN) {
+ pm.onEndTask(taskName, lastWork);
+ } else {
+ int pDone = lastWork * 100 / totalWork;
+ pm.onEndTask(taskName, lastWork, totalWork, pDone);
+ }
+ }
+ if (timerFuture != null)
+ timerFuture.cancel(false /* no interrupt */);
+ }
+ }
+}
--- /dev/null
+/**
+ *
+ */
+package org.tizen.core.ide;
+
+/**
+ * This progress monitor do not propagate any message.
+ *
+ * @author Harry Hyeongseok Heo{@literal <hyeongseok.heo@samsung.com>} (S-core)
+ */
+public class NullProgressMonitor implements ProgressMonitor {
+
+ /* (non-Javadoc)
+ * @see org.tizen.core.ide.ProgressMonitor#start(int)
+ */
+ @Override
+ public void start(int totalTasks) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.tizen.core.ide.ProgressMonitor#beginTask(java.lang.String, int)
+ */
+ @Override
+ public void beginTask(String title, int totalWork) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.tizen.core.ide.ProgressMonitor#update(int)
+ */
+ @Override
+ public void update(int completed) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.tizen.core.ide.ProgressMonitor#endTask()
+ */
+ @Override
+ public void endTask() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.tizen.core.ide.ProgressMonitor#isCancelled()
+ */
+ @Override
+ public boolean isCancelled() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.tizen.core.ide;
+
+/** A progress reporting interface. */
+public interface ProgressMonitor {
+ /** Constant indicating the total work units cannot be predicted. */
+ public static final int UNKNOWN = 0;
+
+ /**
+ * Advise the monitor of the total number of subtasks.
+ * <p>
+ * This should be invoked at most once per progress monitor interface.
+ *
+ * @param totalTasks
+ * the total number of tasks the caller will need to complete
+ * their processing.
+ */
+ void start(int totalTasks);
+
+ /**
+ * Begin processing a single task.
+ *
+ * @param title
+ * title to describe the task. Callers should publish these as
+ * stable string constants that implementations could match
+ * against for translation support.
+ * @param totalWork
+ * total number of work units the application will perform;
+ * {@link #UNKNOWN} if it cannot be predicted in advance.
+ */
+ void beginTask(String title, int totalWork);
+
+ /**
+ * Denote that some work units have been completed.
+ * <p>
+ * This is an incremental update; if invoked once per work unit the correct
+ * value for our argument is <code>1</code>, to indicate a single unit of
+ * work has been finished by the caller.
+ *
+ * @param completed
+ * the number of work units completed since the last call.
+ */
+ void update(int completed);
+
+ /** Finish the current task, so the next can begin. */
+ void endTask();
+
+ /**
+ * Check for user task cancellation.
+ *
+ * @return true if the user asked the process to stop working.
+ */
+ boolean isCancelled();
+}
--- /dev/null
+/*
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.tizen.core.ide;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+/** A simple progress reporter printing on a stream. */
+public class TextProgressMonitor extends BatchingProgressMonitor {
+ private final Writer out;
+
+ private boolean write;
+
+ /** Initialize a new progress monitor. */
+ public TextProgressMonitor() {
+ this(new PrintWriter(System.err));
+ }
+
+ /**
+ * Initialize a new progress monitor.
+ *
+ * @param out
+ * the stream to receive messages on.
+ */
+ public TextProgressMonitor(Writer out) {
+ this.out = out;
+ this.write = true;
+ }
+
+ @Override
+ protected void onUpdate(String taskName, int workCurr) {
+ StringBuilder s = new StringBuilder();
+ format(s, taskName, workCurr);
+ send(s);
+ }
+
+ @Override
+ protected void onEndTask(String taskName, int workCurr) {
+ StringBuilder s = new StringBuilder();
+ format(s, taskName, workCurr);
+ s.append("\n"); //$NON-NLS-1$
+ send(s);
+ }
+
+ private void format(StringBuilder s, String taskName, int workCurr) {
+ s.append("\r"); //$NON-NLS-1$
+ s.append(taskName);
+ s.append(": "); //$NON-NLS-1$
+ while (s.length() < 25)
+ s.append(' ');
+ s.append(workCurr);
+ }
+
+ @Override
+ protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt) {
+ StringBuilder s = new StringBuilder();
+ format(s, taskName, cmp, totalWork, pcnt);
+ send(s);
+ }
+
+ @Override
+ protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt) {
+ StringBuilder s = new StringBuilder();
+ format(s, taskName, cmp, totalWork, pcnt);
+ s.append("\n"); //$NON-NLS-1$
+ send(s);
+ }
+
+ private void format(StringBuilder s, String taskName, int cmp,
+ int totalWork, int pcnt) {
+ s.append("\r"); //$NON-NLS-1$
+ s.append(taskName);
+ s.append(": "); //$NON-NLS-1$
+ while (s.length() < 25)
+ s.append(' ');
+
+ String endStr = String.valueOf(totalWork);
+ String curStr = String.valueOf(cmp);
+ while (curStr.length() < endStr.length())
+ curStr = " " + curStr; //$NON-NLS-1$
+ if (pcnt < 100)
+ s.append(' ');
+ if (pcnt < 10)
+ s.append(' ');
+ s.append(pcnt);
+ s.append("% ("); //$NON-NLS-1$
+ s.append(curStr);
+ s.append("/"); //$NON-NLS-1$
+ s.append(endStr);
+ s.append(")"); //$NON-NLS-1$
+ }
+
+ private void send(StringBuilder s) {
+ if (write) {
+ try {
+ out.write(s.toString());
+ out.flush();
+ } catch (IOException err) {
+ write = false;
+ }
+ }
+ }
+}
}
//Common
public static String CANNOT_READ_CPROJECT;
- public static String CANNOT_GET_OPTIONS;
+ public static String CANNOT_SET_OPTIONS;
public static String INVALID_ARG;
public static String INVALID_ARGS;
public static String BN_CANNOT_MAKE_BUILD_COMMAND;
public static String BN_CANNOT_SET_BUILD_TARGET;
public static String BN_CANNOT_WRITE_BUILD_TARGET_INFO;
- public static String BN_CANNOT_FIND_DEFAULT_INFO_CONFIG;
public static String BN_INVALID_CONFIGURATION;
- public static String BN_NO_BUILD_INPUT;
+ public static String BN_NO_CONFIG_BUILD_ARCHITECTURE;
+ public static String BN_NO_CONFIG_BUILD_CONFIGURATION;
+ public static String BN_NO_CONFIG_BUILD_COMPILER;
public static String BN_SUCCESS_SET_TARGET_INFO;
CANNOT_READ_CPROJECT = Can not read the .cproject file.
-CANNOT_GET_OPTIONS = Can not get the required options.
+CANNOT_SET_OPTIONS = Can not set the options.
INVALID_ARG = The {0} is an invalid argument\nTry to use one of {1}
INVALID_ARGS = There are invalid arguments.
BN_CANNOT_MAKE_BUILD_COMMAND = Can not make the build command.
BN_CANNOT_SET_BUILD_TARGET = Can not set the build target information.
BN_CANNOT_WRITE_BUILD_TARGET_INFO = Can not write the build target information.
-BN_CANNOT_FIND_DEFAULT_INFO_CONFIG = Can not read the {0} value in config file.
BN_INVALID_CONFIGURATION = The {0} is an invalid configuration\nTry to use one of {1}
-BN_NO_BUILD_INPUT = There is no {0} input. -> Try to find default value from config file.
+BN_NO_CONFIG_BUILD_ARCHITECTURE = There is no default architecture value in config file.
+BN_NO_CONFIG_BUILD_COMPILER = There is no default compiler value in config file.
+BN_NO_CONFIG_BUILD_CONFIGURATION = There is no default configuration value in config file.
BN_SUCCESS_SET_TARGET_INFO = Success to write the build target information
public class BuildNativeCLI extends AbstractCLI {\r
private Logger log = LoggerFactory.getLogger(getClass());\r
\r
- @Option(name = "--arch", metaVar = "x86 | arm", usage = "Architecture for build result")\r
+ @Option(name = "--arch", depends="--compiler", metaVar = "x86 | arm", usage = "Architecture for build result")\r
private String architecture;\r
\r
- @Option(name = "--compiler", metaVar = "gcc | llvm", usage = "Compiler for build result")\r
+ @Option(name = "--compiler", depends="--arch", metaVar = "gcc | llvm", usage = "Compiler for build result")\r
private String compiler;\r
\r
@Option(name = "--configuration", metaVar = "Debug | Release | DA", usage = "Configuration for build result")\r
*/\r
@Override\r
public void execute() {\r
- log.trace("Execute BuildNativeCLI...");\r
+ log.trace("Execute BuildWebCLI...");\r
\r
BuildNativeCLICommand command = new BuildNativeCLICommand();\r
\r
command.setWorkingDir(workingDir == null ? currentWorkspacePath : workingDir);\r
- configuration = DA.equals(configuration) ? DA_ORIGIN : configuration;\r
- command.setRequiredOptions(new String[]{architecture, compiler, configuration});\r
+ command.setArchitecture(architecture);\r
+ command.setCompiler(compiler);\r
+ command.setConfiguration(DA.equals(configuration) ? DA_ORIGIN : configuration);\r
command.setPredefineOption(predefineOption);\r
\r
BuildNative runCommand = command.runCommand();\r
@Override
public void execute() {
- log.trace("Execute ListCLI...");
if( null != this.tizenCLI) {
this.tizenCLI.execute();
}
*/\r
@Override\r
public void execute() {\r
- log.trace("Execute SignCLI...");\r
+ log.trace("Execute Signing...");\r
\r
SignCLICommand command = new SignCLICommand();\r
\r