[Title] SDB Refactoring #1
authorBonyong.lee <bonyong.lee@samsung.com>
Tue, 21 May 2013 06:31:38 +0000 (15:31 +0900)
committerBonyong.lee <bonyong.lee@samsung.com>
Tue, 21 May 2013 06:31:38 +0000 (15:31 +0900)
[Desc.] Remove unused method and class, categorize class, and Fix detail
bug
[Issue]

74 files changed:
org.tizen.common.connection/META-INF/MANIFEST.MF
org.tizen.common.connection/src/org/tizen/common/connection/ConnectionPlugin.java
org.tizen.common.connection/src/org/tizen/common/connection/ddmuilib/SyncProgressMonitor.java
org.tizen.common.connection/src/org/tizen/common/connection/debugtools/OnDemandInstall.java
org.tizen.common.connection/src/org/tizen/common/connection/explorer/ConnectionExplorerContentProvider.java
org.tizen.common.connection/src/org/tizen/common/connection/explorer/ConnectionExplorerLabelProvider.java
org.tizen.common.connection/src/org/tizen/common/connection/explorer/ConnectionExplorerPanel.java
org.tizen.common.connection/src/org/tizen/common/connection/log/LogPanel.java
org.tizen.common.connection/src/org/tizen/common/connection/log/LogTab.java
org.tizen.common.connection/src/org/tizen/common/connection/preference/TizenLogPreferencePage.java
org.tizen.common.connection/src/org/tizen/common/connection/properties/ConnectionExplorerInfoPropertyPages.java
org.tizen.common.connection/src/org/tizen/common/connection/properties/ConnectionExplorerPermissionPropertyPages.java
org.tizen.common.connection/src/org/tizen/common/connection/sdblib/dnd/FileEntryDropAdapter.java
org.tizen.common.connection/src/org/tizen/common/connection/sdblib/dnd/FileEntryTransfer.java
org.tizen.common.connection/src/org/tizen/common/connection/ui/ConnectionExplorer.java
org.tizen.common.connection/src/org/tizen/common/connection/ui/LogView.java
org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileContentProvider.java
org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileDialog.java
org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileLabelProvider.java
org.tizen.common.sdblib/META-INF/MANIFEST.MF
org.tizen.common.sdblib/src/org/tizen/sdblib/Arch.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/ArrayHelper.java [deleted file]
org.tizen.common.sdblib/src/org/tizen/sdblib/CrashReportService.java [deleted file]
org.tizen.common.sdblib/src/org/tizen/sdblib/Device.java
org.tizen.common.sdblib/src/org/tizen/sdblib/DeviceMonitor.java
org.tizen.common.sdblib/src/org/tizen/sdblib/DeviceState.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/IDebugBridgeChangeListener.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/IDevice.java
org.tizen.common.sdblib/src/org/tizen/sdblib/IDeviceChangeListener.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/IShellOutputReceiver.java
org.tizen.common.sdblib/src/org/tizen/sdblib/LogReceiver.java
org.tizen.common.sdblib/src/org/tizen/sdblib/MultiLineReceiver.java [deleted file]
org.tizen.common.sdblib/src/org/tizen/sdblib/NullOutputReceiver.java [deleted file]
org.tizen.common.sdblib/src/org/tizen/sdblib/SdbHelper.java
org.tizen.common.sdblib/src/org/tizen/sdblib/SdbResponse.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/SdbShellProcess.java [deleted file]
org.tizen.common.sdblib/src/org/tizen/sdblib/SmartDevelopmentBridge.java
org.tizen.common.sdblib/src/org/tizen/sdblib/SmartDevelopmentBridgetConstants.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/AbstractServer.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/Server.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/ServerState.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/exception/ServerException.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/AbstractShellOutputReceiver.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/MultiLineReceiver.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/NullOutputReceiver.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/service/CrashReportService.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/service/FileListingService.java [moved from org.tizen.common.sdblib/src/org/tizen/sdblib/FileListingService.java with 97% similarity]
org.tizen.common.sdblib/src/org/tizen/sdblib/service/SyncService.java [moved from org.tizen.common.sdblib/src/org/tizen/sdblib/SyncService.java with 97% similarity, mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/ArrayUtil.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/Assert.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/CollectionUtil.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/IOUtil.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/Log.java [moved from org.tizen.common.sdblib/src/org/tizen/sdblib/Log.java with 77% similarity]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/LogLevel.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/MapUtil.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/ObjectUtil.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/ParsingUtil.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/Preferences.java [moved from org.tizen.common.sdblib/src/org/tizen/sdblib/SdbPreferences.java with 56% similarity]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/SdbShellProcess.java
org.tizen.common.sdblib/src/org/tizen/sdblib/util/StreamGobbler.java [new file with mode: 0644]
org.tizen.common.sdblib/src/org/tizen/sdblib/util/StringUtil.java [new file with mode: 0644]
org.tizen.common/META-INF/MANIFEST.MF
org.tizen.common/src/org/tizen/common/CommonPlugin.java
org.tizen.common/src/org/tizen/common/core/command/sdb/PullSdbCommand.java
org.tizen.common/src/org/tizen/common/core/command/sdb/PushSdbCommand.java
org.tizen.common/src/org/tizen/common/core/command/sdb/ShellSdbCommand.java
org.tizen.common/src/org/tizen/common/core/command/sdb/SmartDevelopmentBridgeManager.java
org.tizen.common/src/org/tizen/common/rds/RdsDeltaDetector.java
org.tizen.common/src/org/tizen/common/rds/RdsDeployer.java
org.tizen.common/src/org/tizen/common/sdb/command/receiver/CommandOutputReceiver.java
org.tizen.common/test/src/org/tizen/common/core/command/sdb/DlogSdbCommandTest.java
org.tizen.common/test/src/org/tizen/common/core/command/sdb/PullSdbCommandTest.java
org.tizen.common/test/src/org/tizen/common/core/command/sdb/PushSdbCommandTest.java
org.tizen.common/test/src/org/tizen/common/core/command/sdb/ShellSdbCommandTest.java

index 3a61520..a5c49bc 100644 (file)
@@ -13,7 +13,12 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Import-Package: org.eclipse.ui.console,
  org.tizen.common.util,
- org.tizen.sdblib
+ org.tizen.sdblib,
+ org.tizen.sdblib.daemon,
+ org.tizen.sdblib.exception,
+ org.tizen.sdblib.receiver,
+ org.tizen.sdblib.service,
+ org.tizen.sdblib.util
 Bundle-ClassPath: .
 Export-Package: org.tizen.common.connection;
   uses:="org.eclipse.jface.resource,
index 314aaa8..9157ffa 100755 (executable)
@@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory;
 import org.tizen.common.connection.preference.TizenConnectionExplorerPreferencePage;
 import org.tizen.common.connection.preference.TizenLogPreferencePage;
 import org.tizen.common.util.OSChecker;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.SmartDevelopmentBridge;
 
index 37e2035..a888fe6 100644 (file)
@@ -20,7 +20,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.swt.widgets.Label;
 import org.tizen.common.ui.dialog.TransferProgressMonitorDialog;
 import org.tizen.common.util.SWTUtil;
-import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.service.SyncService.ISyncProgressMonitor;
 
 /**
  * Implementation of the {@link ISyncProgressMonitor} wrapping an Eclipse {@link IProgressMonitor}.
index 3b7bc93..aaee894 100644 (file)
@@ -47,11 +47,11 @@ import org.tizen.common.TizenPlatformConstants;
 import org.tizen.common.core.application.InstallPathConfig;
 import org.tizen.common.util.FileUtil;
 import org.tizen.common.util.IOUtil;
+import org.tizen.sdblib.Arch;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.IDevice.Arch;
-import org.tizen.sdblib.MultiLineReceiver;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.SyncResult;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.SyncResult;
 
 /**
  * On-demand Install class to deploy SDK tools to Tizen device or an emulator.
index 238ee38..a8570bf 100755 (executable)
  */
 package org.tizen.common.connection.explorer;
 
-import static org.tizen.sdblib.FileListingService.TYPE_DIRECTORY;
-import static org.tizen.sdblib.FileListingService.TYPE_DIRECTORY_LINK;
-import static org.tizen.sdblib.FileListingService.TYPE_LINK;
-import static org.tizen.sdblib.FileListingService.TYPE_ROOT_DEVICE;
-import static org.tizen.sdblib.FileListingService.TYPE_ROOT_EMULATOR;
+import static org.tizen.sdblib.service.FileListingService.TYPE_DIRECTORY;
+import static org.tizen.sdblib.service.FileListingService.TYPE_DIRECTORY_LINK;
+import static org.tizen.sdblib.service.FileListingService.TYPE_LINK;
+import static org.tizen.sdblib.service.FileListingService.TYPE_ROOT_DEVICE;
+import static org.tizen.sdblib.service.FileListingService.TYPE_ROOT_EMULATOR;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -38,7 +38,7 @@ import java.util.Set;
 
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.SmartDevelopmentBridge;
 
index c9a59c4..9a0c3c4 100755 (executable)
@@ -31,8 +31,8 @@ import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Display;
 import org.tizen.common.connection.ConnectionPlugin;
 import org.tizen.common.util.SWTUtil;
-import org.tizen.sdblib.FileListingService;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
 
 public class ConnectionExplorerLabelProvider implements ITableLabelProvider
index 0688f39..36323f7 100755 (executable)
@@ -90,15 +90,15 @@ import org.tizen.common.ui.view.console.ConsoleManager;
 import org.tizen.common.util.DialogUtil;
 import org.tizen.common.util.FilenameUtil;
 import org.tizen.common.util.log.Logger;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.IDebugBridgeChangeListener;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.MultiLineReceiver;
+import org.tizen.sdblib.IDeviceChangeListener;
 import org.tizen.sdblib.SmartDevelopmentBridge;
-import org.tizen.sdblib.SmartDevelopmentBridge.IDebugBridgeChangeListener;
-import org.tizen.sdblib.SmartDevelopmentBridge.IDeviceChangeListener;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
-import org.tizen.sdblib.SyncService.SyncResult;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.service.SyncService.SyncResult;
 
 public class ConnectionExplorerPanel extends Panel implements IDeviceChangeListener, IDebugBridgeChangeListener, ISelectionListener
 {
@@ -988,7 +988,7 @@ public class ConnectionExplorerPanel extends Panel implements IDeviceChangeListe
      * @see IDeviceChangeListener#deviceConnected(IDevice)
      */
     @Override
-    public void deviceConnected(IDevice device)
+    public void onConnected(IDevice device)
     {
         if (device.isOffline())
         {
@@ -1005,18 +1005,18 @@ public class ConnectionExplorerPanel extends Panel implements IDeviceChangeListe
     }
 
     @Override
-    public void deviceDisconnected(IDevice device)
+    public void onDisconnected(IDevice device)
     {
         devicesList.remove(device);
         execRefresh();
     }
 
     @Override
-    public void deviceChanged(IDevice device, int changeMask)
+    public void onChanged(IDevice device, int changeMask)
     {
         if (changeMask == 1)
         {
-            deviceConnected(device);
+            onConnected(device);
         }
     }
 
index 68bf86b..ba0341f 100755 (executable)
@@ -76,9 +76,9 @@ import org.tizen.common.util.NotificationType;
 import org.tizen.common.util.NotifierDialog;
 import org.tizen.common.util.SWTUtil;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.Log.LogLevel;
 import org.tizen.sdblib.SmartDevelopmentBridge;
-import org.tizen.sdblib.SmartDevelopmentBridge.IDeviceChangeListener;
+import org.tizen.sdblib.IDeviceChangeListener;
+import org.tizen.sdblib.util.LogLevel;
 
 public class LogPanel extends Panel implements IDeviceChangeListener
 {
@@ -836,16 +836,16 @@ public class LogPanel extends Panel implements IDeviceChangeListener
     }
 
     @Override
-    public void deviceConnected(IDevice device)
+    public void onConnected(IDevice device)
     {
         if (device.isOnline())
         {
-            deviceChanged(device, 1);
+            onChanged(device, 1);
         }
     }
 
     @Override
-    public void deviceDisconnected(final IDevice device)
+    public void onDisconnected(final IDevice device)
     {
 
         if (parent.isDisposed() == false)
@@ -881,7 +881,7 @@ public class LogPanel extends Panel implements IDeviceChangeListener
     }
 
     @Override
-    public void deviceChanged(final IDevice device, int changeMask)
+    public void onChanged(final IDevice device, int changeMask)
     {
         if (changeMask == 1)
         {
@@ -939,7 +939,7 @@ public class LogPanel extends Panel implements IDeviceChangeListener
             LogLevel level = null;
             if(oldTab == null)
             {
-                level = LogLevel.getByString(ConnectionPlugin.getDefault().getPreferenceStore().getString(TizenLogPreferencePage.KEY_DEFAULT_LEVEL));
+                level = LogLevel.getByName(ConnectionPlugin.getDefault().getPreferenceStore().getString(TizenLogPreferencePage.KEY_DEFAULT_LEVEL));
             }
             else
             {
index 84c6ff0..bf527ec 100755 (executable)
@@ -47,8 +47,8 @@ import org.tizen.common.ui.view.console.AnsicodeAdapter;
 import org.tizen.common.util.StringUtil;
 import org.tizen.common.util.log.Logger;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.Log.LogLevel;
-import org.tizen.sdblib.MultiLineReceiver;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
+import org.tizen.sdblib.util.LogLevel;
 
 public class LogTab
 {
@@ -112,7 +112,7 @@ public class LogTab
         logTabName = pName;
         device = pDevice;
         this.colors = pColors;
-        defaultLevel = LogLevel.getByString(ConnectionPlugin.getDefault().getPreferenceStore().getString(TizenLogPreferencePage.KEY_DEFAULT_LEVEL));
+        defaultLevel = LogLevel.getByName(ConnectionPlugin.getDefault().getPreferenceStore().getString(TizenLogPreferencePage.KEY_DEFAULT_LEVEL));
     }
 
     public LogTab()
@@ -254,7 +254,7 @@ public class LogTab
     
     public void start()
     {
-        LogLevel level = LogLevel.getByString(ConnectionPlugin.getDefault().getPreferenceStore().getString(TizenLogPreferencePage.KEY_DEFAULT_LEVEL));
+        LogLevel level = LogLevel.getByName(ConnectionPlugin.getDefault().getPreferenceStore().getString(TizenLogPreferencePage.KEY_DEFAULT_LEVEL));
         start(level);
     }
 
@@ -289,7 +289,7 @@ public class LogTab
 
                     try
                     {
-                        device.executeShellCommand(String.format(TizenPlatformConstants.DLOGUTIL_CMD, "-v long *:" + level.getPriorityLetter()), logReceiver, 0 /* timeout */); //$NON-NLS-1$
+                        device.executeShellCommand(String.format(TizenPlatformConstants.DLOGUTIL_CMD, "-v long *:" + level.getLetter()), logReceiver, 0 /* timeout */); //$NON-NLS-1$
                     } catch (Exception e)
                     {
                         Logger.error("LogTab", e);
@@ -621,7 +621,7 @@ public class LogTab
         {
             super();
 
-            setTrimLine(false);
+            setTrimLines(false);
         }
 
         @Override
index ae1c759..563451f 100644 (file)
@@ -39,7 +39,7 @@ import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.tizen.common.connection.ConnectionPlugin;
 import org.tizen.common.util.SWTUtil;
-import org.tizen.sdblib.Log.LogLevel;
+import org.tizen.sdblib.util.LogLevel;
 
 public class TizenLogPreferencePage extends FieldEditorPreferencePage implements
         IWorkbenchPreferencePage
@@ -48,7 +48,7 @@ public class TizenLogPreferencePage extends FieldEditorPreferencePage implements
     public static final String id = "org.tizen.common.connection.preferences.tizenlog";
     public static final String KEY_DEFAULT_LEVEL = "default_log_level"; //$NON-NLS-1$
 
-    public static final String VALUE_DEFAULT_LEVEL = LogLevel.VERBOSE.getStringValue();
+    public static final String VALUE_DEFAULT_LEVEL = LogLevel.VERBOSE.getName();
 
     public TizenLogPreferencePage()
     {
@@ -84,11 +84,11 @@ public class TizenLogPreferencePage extends FieldEditorPreferencePage implements
         Composite comp = SWTUtil.createGroup(parent, PreferenceMessages.LOG_GROUP_LEVEL, 1);
         Composite formatComposite = SWTUtil.createCompositeEx(comp, 1, GridData.BEGINNING);
 
-        String[][] levels = { { LogLevel.VERBOSE.toString(), LogLevel.VERBOSE.getStringValue() },
-                { LogLevel.DEBUG.toString(), LogLevel.DEBUG.getStringValue() },
-                { LogLevel.INFO.toString(), LogLevel.INFO.getStringValue() },
-                { LogLevel.WARN.toString(), LogLevel.WARN.getStringValue() },
-                { LogLevel.ERROR.toString(), LogLevel.ERROR.getStringValue() } };
+        String[][] levels = { { LogLevel.VERBOSE.toString(), LogLevel.VERBOSE.getName() },
+                { LogLevel.DEBUG.toString(), LogLevel.DEBUG.getName() },
+                { LogLevel.INFO.toString(), LogLevel.INFO.getName() },
+                { LogLevel.WARN.toString(), LogLevel.WARN.getName() },
+                { LogLevel.ERROR.toString(), LogLevel.ERROR.getName() } };
 
         RadioGroupFieldEditor radioField = new RadioGroupFieldEditor(KEY_DEFAULT_LEVEL,
                 "", 1, levels, formatComposite);
index 4e333b1..313e57b 100644 (file)
@@ -34,8 +34,8 @@ import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.IWorkbenchPropertyPage;
 import org.eclipse.ui.dialogs.PropertyPage;
 
-import org.tizen.sdblib.FileListingService;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 
 public class ConnectionExplorerInfoPropertyPages extends PropertyPage implements IWorkbenchPropertyPage {
 
index f286a6f..9c7367c 100755 (executable)
@@ -37,8 +37,8 @@ import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.ui.dialogs.PropertyPage;
 
-import org.tizen.sdblib.FileListingService;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 
 public class ConnectionExplorerPermissionPropertyPages extends PropertyPage {
 
index 6c08513..4b27522 100755 (executable)
@@ -39,9 +39,9 @@ import org.tizen.common.connection.ddmuilib.FileDialogUtils;
 import org.tizen.common.connection.ddmuilib.console.DdmConsole;
 import org.tizen.common.util.IOUtil;
 import org.tizen.sdblib.SdbCommandRejectedException;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
-import org.tizen.sdblib.SyncService.SyncResult;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.service.SyncService.SyncResult;
 import org.tizen.sdblib.TimeoutException;
 
 public class FileEntryDropAdapter implements IDropActionDelegate {
index 391ce7f..9631169 100644 (file)
@@ -34,7 +34,7 @@ import java.io.IOException;
 import org.eclipse.swt.dnd.ByteArrayTransfer;
 
 import org.tizen.common.util.log.Logger;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 
 public class FileEntryTransfer extends ByteArrayTransfer {
 
index 43cce81..b9800a2 100755 (executable)
@@ -65,10 +65,10 @@ import org.tizen.common.util.NotificationType;
 import org.tizen.common.util.NotifierDialog;
 import org.tizen.common.util.SWTUtil;
 import org.tizen.common.util.log.Logger;
-import org.tizen.sdblib.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.MultiLineReceiver;
 import org.tizen.sdblib.SmartDevelopmentBridge;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 
 public class ConnectionExplorer extends ViewPart implements IPartListener2 {
 
index 996d672..7966b0b 100755 (executable)
@@ -43,7 +43,7 @@ import org.tizen.common.connection.ConnectionPlugin;
 import org.tizen.common.connection.log.LogColors;
 import org.tizen.common.connection.log.LogPanel;
 import org.tizen.common.connection.preference.TizenLogPreferencePage;
-import org.tizen.sdblib.Log.LogLevel;
+import org.tizen.sdblib.util.LogLevel;
 
 /**
  * The log cat view displays log output from the current device selection.
@@ -167,7 +167,7 @@ public final class LogView extends ViewPart
         levelFilterActions = new Action[logLevelIcons.length];
         for (int i = 0; i < levelFilterActions.length; i++)
         {
-            String name = levels[i].getStringValue();
+            String name = levels[i].getName();
             levelFilterActions[i] = new Action(name, IAction.AS_CHECK_BOX)
             {
                 @Override
index 9bf29e2..5f71ac5 100755 (executable)
@@ -31,8 +31,8 @@ import java.util.List;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
-import org.tizen.sdblib.FileListingService;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 
 public class TizenRemoteFileContentProvider  implements ITreeContentProvider {
 
index eab7bb4..d8da8c9 100755 (executable)
@@ -48,7 +48,7 @@ import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeColumn;
 import org.eclipse.swt.widgets.TreeItem;
 import org.tizen.common.connection.ConnectionPlugin;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
 
 public class TizenRemoteFileDialog {
index 160a675..f0b2e3d 100755 (executable)
@@ -30,8 +30,8 @@ import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Display;
 
-import org.tizen.sdblib.FileListingService;
-import org.tizen.sdblib.FileListingService.FileEntry;
+import org.tizen.sdblib.service.FileListingService;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
 
 public class TizenRemoteFileLabelProvider implements ITableLabelProvider {
index 0942f33..6529013 100644 (file)
@@ -5,4 +5,9 @@ Bundle-Vendor: %Bundle-Vendor
 Bundle-SymbolicName: org.tizen.common.sdblib
 Bundle-Version: 2.0.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Export-Package: org.tizen.sdblib
+Export-Package: org.tizen.sdblib,
+ org.tizen.sdblib.daemon,
+ org.tizen.sdblib.exception,
+ org.tizen.sdblib.receiver,
+ org.tizen.sdblib.service,
+ org.tizen.sdblib.util
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/Arch.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/Arch.java
new file mode 100644 (file)
index 0000000..6705c21
--- /dev/null
@@ -0,0 +1,75 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib;\r
+\r
+/**\r
+ * The architecture of a device.\r
+ * Returns {@link Arch#X86} or {@link Arch#ARM} about device architecture.\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+public enum\r
+Arch\r
+{\r
+    /**\r
+     * X86 archietecture\r
+     */\r
+    X86( "86" ),\r
+    \r
+    /**\r
+     * ARM archietecture\r
+     */\r
+    ARM( "arm" );\r
+\r
+    /**\r
+     * Archietecture name\r
+     */\r
+    private String arch;\r
+\r
+    /**\r
+     * Constructor with archietecture name\r
+     * \r
+     * @param arch archietecture name\r
+     */\r
+    Arch(\r
+       final String arch\r
+    )\r
+    {\r
+        this.arch = arch;\r
+    }\r
+\r
+    /**\r
+     * Returns archietecture name\r
+     * \r
+     * @return {@link #arch}\r
+     */\r
+    public\r
+    String\r
+    getArch()\r
+    {\r
+        return arch;\r
+    }\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/ArrayHelper.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/ArrayHelper.java
deleted file mode 100755 (executable)
index 6778c85..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 org.tizen.sdblib;
-
-/**
- * Utility class providing array to int/long conversion for data received from devices through sdb. 
- */
-public final class
-ArrayHelper
-{
-       
-       protected ArrayHelper() {}
-
-    /**
-     * Swaps an unsigned value around, and puts the result in an array that can be sent to a device.
-     * @param value The value to swap.
-     * @param dest the destination array
-     * @param offset the offset in the array where to put the swapped value.
-     *      Array length must be at least offset + 4
-     */
-    public static
-    void
-    swap32bitsToArray(
-       final int value,
-       final byte[] dest,
-       final int offset
-    )
-    {
-        dest[offset] = (byte)(value & 0x000000FF);
-        dest[offset + 1] = (byte)((value & 0x0000FF00) >> 8);
-        dest[offset + 2] = (byte)((value & 0x00FF0000) >> 16);
-        dest[offset + 3] = (byte)((value & 0xFF000000) >> 24);
-    }
-
-    /**
-     * Reads a signed 32 bit integer from an array coming from a device.
-     * @param value the array containing the int
-     * @param offset the offset in the array at which the int starts
-     * @return the integer read from the array
-     */
-    public static
-    int
-    swap32bitFromArray(
-       final byte[] value,
-       final int offset
-    )
-    {
-        return (((int)value[offset]) & 0x000000FF)
-        | ((((int)value[offset + 1]) & 0x000000FF) << 8)
-        | ((((int)value[offset + 2]) & 0x000000FF) << 16)
-        | ((((int)value[offset + 3]) & 0x000000FF) << 24);
-    }
-    
-    /**
-     * Reads an unsigned 16 bit integer from an array coming from a device,
-     * and returns it as an 'int'
-     * @param value the array containing the 16 bit int (2 byte).
-     * @param offset the offset in the array at which the int starts
-     *      Array length must be at least offset + 2
-     * @return the integer read from the array.
-     */
-    public static
-    int
-    swapU16bitFromArray(
-       final byte[] value,
-       final int offset
-    )
-    {
-        return (((int)value[offset]) & 0x000000FF )
-        | ((((int)value[offset + 1]) & 0x000000FF) << 8);
-    }
-    
-    /**
-     * Reads a signed 64 bit integer from an array coming from a device.
-     * @param value the array containing the int
-     * @param offset the offset in the array at which the int starts
-     *      Array length must be at least offset + 8
-     * @return the integer read from the array
-     */
-    public static
-    long
-    swap64bitFromArray(
-       final byte[] value,
-       final int offset
-    )
-    {
-        return (((long)value[offset]) & 0x00000000000000FFL)
-        | ((((long)value[offset + 1]) & 0x00000000000000FFL) << 8)
-        | ((((long)value[offset + 2]) & 0x00000000000000FFL) << 16)
-        | ((((long)value[offset + 3]) & 0x00000000000000FFL) << 24)
-        | ((((long)value[offset + 4]) & 0x00000000000000FFL) << 32)
-        | ((((long)value[offset + 5]) & 0x00000000000000FFL) << 40)
-        | ((((long)value[offset + 6]) & 0x00000000000000FFL) << 48)
-        | ((((long)value[offset + 7]) & 0x00000000000000FFL) << 56);
-    }
-}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/CrashReportService.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/CrashReportService.java
deleted file mode 100644 (file)
index 074843c..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * CrashReportService
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * Kangho Kim <kh5325.kim@samsung.com>
- * Yoonki Park <yoonki.park@samsung.com>
- * 
- * 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.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-package org.tizen.sdblib;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.tizen.sdblib.SdbHelper.SdbResponse;
-import org.tizen.sdblib.SmartDevelopmentBridge.IDeviceChangeListener;
-
-/**
- * CrashReportService provides notification to all listeners when a cs file is created.
- * 
- *  <p/>It is needed to implement {@link ICSServiceListener} for getting the service.
- * @author yoonki.park<yoonki.park@samsung.com>
- * 
- */
-public final class CrashReportService implements IDeviceChangeListener {
-    private final static List<ICrashReportServiceListener> mCSListeners = new ArrayList<ICrashReportServiceListener>();
-    private static CrashReportService mInstance;
-    private Selector mSelector = null;
-    private volatile boolean finished = false;
-
-    private CrashReportService() throws IOException {
-        mSelector = Selector.open();
-        SmartDevelopmentBridge.addDeviceChangeListener(this);
-    }
-
-    /**
-     * Gets crash report service.
-     * @return
-     * @throws IOException
-     */
-    public static synchronized CrashReportService getService() throws IOException {
-        if (mInstance == null) {
-            mInstance = new CrashReportService();
-        }
-
-        return mInstance;
-    }
-
-    /**
-     * Initializes report channels when Tizen device are connected right after
-     * launching IDE.
-     */
-    private void initReportChannel() {
-        IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
-        for (IDevice device : devices) {
-            if (device.isOnline()) {
-                registerReportChannel(device);
-            }
-        }
-    }
-
-    /**
-     * Registers a channel for given device.
-     * 
-     * @param device
-     */
-    private void registerReportChannel(IDevice device) {
-        SocketChannel channel = null;
-
-        InetSocketAddress mAddress = SmartDevelopmentBridge.getSocketAddress();
-        try {
-            channel = SocketChannel.open(mAddress);
-            channel.configureBlocking(false);
-
-            SdbHelper.setDevice(channel, device);
-
-            byte[] request = SdbHelper.formSdbRequest("cs:");
-            SdbHelper.write(channel, request, -1, SdbPreferences.getTimeOut());
-
-            SdbResponse resp = SdbHelper.readSdbResponse(channel, false);
-
-            if (resp.okay == false) {
-                Log.e("sdb", "got unhappy response from sdb cs req: " + resp.message);
-                close(channel);
-                return;
-            }
-            Log.i("sdb", "registering CS Report Service");
-            mSelector.wakeup();
-            channel.register(mSelector, SelectionKey.OP_READ, device);
-            Log.i("sdb", "registered CS Report Service");
-        } catch (IOException e) {
-            Log.e("sdb", "failed to open a socket channel");
-        }
-    }
-
-    /**
-     * Starts CS Report Service
-     */
-    public void startService() {
-        new Thread("CS Report Service") {
-            @Override
-            public void run() {
-                Log.i("sdb", "starting CS Report Service");
-                initReportChannel(); // TODO : should moved to deviceConnected event
-                try {
-                    while (!finished) {
-                        if (mSelector.select() <= 0) { //spin-wait sleep, in ms
-                            Thread.sleep(SdbHelper.WAIT_TIME);
-                            continue;
-                        }
-                        Iterator<SelectionKey> it = mSelector.selectedKeys().iterator();
-                        while (it.hasNext()) {
-                            SelectionKey key = it.next();
-                            if (key.isConnectable()) {
-                                SocketChannel sc = (SocketChannel) key.channel();
-                                if (sc.isConnectionPending()) {
-                                    sc.finishConnect();
-                                }
-                            } else if (key.isReadable()) {
-                                read(key);
-                            }
-                            it.remove();
-                        }
-                    }
-                } catch (Exception e) {
-                    try {
-                        mSelector.close();
-                        Log.e("sdb", "select failed :" + e);
-                    } catch (IOException e1) {
-                       Log.e("sdb", "selector close failed :" + e);
-                    }
-                }
-            }
-        }.start();
-    }
-
-    /**
-    * Stops CS Report Service
-    */
-    public void stopService()
-    {
-        finished = true;
-        SmartDevelopmentBridge.removeDeviceChangeListener(this);
-    }
-
-    /**
-     * Reads a cs file path from the given key, and send this path to all
-     * listener.
-     * 
-     * @param key
-     *            Selected key.
-     * @return
-     */
-    private void read(SelectionKey key) {
-        SocketChannel sc = (SocketChannel) key.channel();
-        ByteBuffer reply = ByteBuffer.allocate(124);
-        int len = 0;
-
-        Charset charset = Charset.forName(SdbHelper.UTF_ENCODING);
-
-        try {
-            len = sc.read(reply);
-        } catch (IOException e) {
-            key.cancel();
-            close(sc);
-            Log.e("sdb", "read failed :" + e);
-        }
-        reply.flip();
-        Log.i("sdb", "read byte :" + len);
-        if (len < 0) {
-            close(sc);
-        } else {
-            if (len > 0) {
-                notifyAllListeners((IDevice) key.attachment(), charset.decode(reply).toString());
-            }
-        }
-
-        clearBuffer(reply);
-    }
-
-    private void clearBuffer(ByteBuffer buffer) {
-        if (buffer != null) {
-            buffer.clear();
-        }
-    }
-
-    /**
-     * Notifies all listeners of cs file path from the device.
-     * @param device
-     * @param path
-     */
-    private void notifyAllListeners(final IDevice device, final String path) {
-        // TODO : At this time, send to the one listener.
-
-        Log.i("sdb", "cs file is created and notify to " + device.getSerialNumber());
-        synchronized (mCSListeners) {
-            for (ICrashReportServiceListener listener : mCSListeners) {
-                if (device != null) {
-                    try {
-                        listener.fileCreated(device, path);
-                    } catch (Exception e) {
-                        Log.e("sdb", "unexpected error occurred :" + e);
-                    }
-                }
-            }
-        }
-    }
-
-    public static void addCrashReportServiceListener(ICrashReportServiceListener listener) {
-        synchronized (mCSListeners) {
-            if (mCSListeners.contains(listener) == false) {
-                mCSListeners.add(listener);
-            }
-        }
-    }
-
-    public static void removeCrashReportServiceListener(ICrashReportServiceListener listener) {
-        synchronized (mCSListeners) {
-            if (mCSListeners.contains(listener) == true) {
-                mCSListeners.remove(listener);
-            }
-        }
-    }
-
-    @Override
-    public void deviceConnected(IDevice device) {
-        if (device.isOnline()) {
-            Log.i("sdb", "welcome to new connection :" + device.getSerialNumber());
-            registerReportChannel(device);
-        }
-    }
-
-    @Override
-    public void deviceDisconnected(IDevice device) {
-        Log.i("sdb", "bye!:" + device.getSerialNumber());
-    }
-
-    @Override
-    public void deviceChanged(IDevice device, int changeMask) {
-        Log.i("sdb", "welcome to new connection :" + device.getSerialNumber());
-        if (changeMask == 1) {
-            deviceConnected(device);
-        }
-    }
-
-    /**
-     * Closes the connection.
-     */
-    private void close(SocketChannel channel) {
-        if (channel != null) {
-            try {
-                channel.close();
-            } catch (IOException e) {
-               Log.e("sdb", "close failed :" + e);
-            }
-        }
-    }
-}
\ No newline at end of file
index d79a51e..dde8245 100644 (file)
@@ -19,15 +19,25 @@ package org.tizen.sdblib;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.io.InputStreamReader;
+import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.tizen.sdblib.SyncService.SyncResult;
+import org.tizen.sdblib.exception.SdbCommandRejectedException;
+import org.tizen.sdblib.exception.ShellCommandUnresponsiveException;
+import org.tizen.sdblib.exception.TimeoutException;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
+import org.tizen.sdblib.receiver.NullOutputReceiver;
+import org.tizen.sdblib.service.FileListingService;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.SyncResult;
+import org.tizen.sdblib.util.Log;
+import org.tizen.sdblib.util.Preferences;
+import org.tizen.sdblib.util.SdbShellProcess;
 
 /**
  * A Device. It can be a physical device or an emulator.
  */
-final class Device implements IDevice {
+public class Device implements IDevice {
 
     private final static int INSTALL_TIMEOUT = 2 * 60 * 1000; // 2min
 
@@ -120,7 +130,7 @@ final class Device implements IDevice {
     }
 
     public SyncService getSyncService() throws TimeoutException, SdbCommandRejectedException, IOException {
-        SyncService syncService = new SyncService(SmartDevelopmentBridge.getSocketAddress(), this);
+        SyncService syncService = new SyncService(SmartDevelopmentBridge.getBridge(), this);
         if (syncService.openSync()) {
             return syncService;
         }
@@ -162,18 +172,16 @@ final class Device implements IDevice {
                 if (receiver != null && receiver.isCancelled()) {
                     break;
                 }
-                byte[] bytes = s.getBytes();
                 if (receiver != null) {
-                    receiver.addOutput(s.getBytes(), 0, bytes.length);
+                       receiver.append( s );
                 }
             }
             while ((s = stdError.readLine()) != null) {
                 if (receiver != null && receiver.isCancelled()) {
                     break;
                 }
-                byte[] bytes = s.getBytes();
                 if (receiver != null) {
-                    receiver.addOutput(s.getBytes(), 0, bytes.length);
+                       receiver.append( s );
                 }
             }
         } finally {
@@ -219,31 +227,31 @@ final class Device implements IDevice {
 
     public void executeShellCommand(String command, IShellOutputReceiver receiver) throws TimeoutException,
             SdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
-        SdbHelper.executeRemoteCommand(SmartDevelopmentBridge.getSocketAddress(), command, this, receiver,
-                SdbPreferences.getTimeOut());
+        SdbHelper.executeRemoteCommand( SmartDevelopmentBridge.getBridge(), command, this, receiver,
+                Preferences.getTimeOut());
     }
 
     public void executeShellCommand(String command, IShellOutputReceiver receiver, int maxTimeToOutputResponse)
             throws TimeoutException, SdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
-        SdbHelper.executeRemoteCommand(SmartDevelopmentBridge.getSocketAddress(), command, this, receiver,
+        SdbHelper.executeRemoteCommand(SmartDevelopmentBridge.getBridge(), command, this, receiver,
                 maxTimeToOutputResponse);
     }
 
     public void runEventLogService(LogReceiver receiver) throws TimeoutException, SdbCommandRejectedException, IOException {
-        SdbHelper.runEventLogService(SmartDevelopmentBridge.getSocketAddress(), this, receiver);
+        SdbHelper.runEventLogService(SmartDevelopmentBridge.getBridge(), this, receiver);
     }
 
     public void runLogService(String logname, LogReceiver receiver) throws TimeoutException, SdbCommandRejectedException,
             IOException {
-        SdbHelper.runLogService(SmartDevelopmentBridge.getSocketAddress(), this, logname, receiver);
+        SdbHelper.runLogService(SmartDevelopmentBridge.getBridge(), this, logname, receiver);
     }
 
     public void createForward(int localPort, int remotePort) throws TimeoutException, SdbCommandRejectedException, IOException {
-        SdbHelper.createForward(SmartDevelopmentBridge.getSocketAddress(), this, localPort, remotePort);
+        SdbHelper.createForward(SmartDevelopmentBridge.getBridge(), this, localPort, remotePort);
     }
 
     public void removeForward(int localPort, int remotePort) throws TimeoutException, SdbCommandRejectedException, IOException {
-        SdbHelper.removeForward(SmartDevelopmentBridge.getSocketAddress(), this, localPort, remotePort);
+        SdbHelper.removeForward(SmartDevelopmentBridge.getBridge(), this, localPort, remotePort);
     }
 
     Device(DeviceMonitor monitor, String serialNumber, DeviceState deviceState) {
@@ -330,7 +338,7 @@ final class Device implements IDevice {
             ShellCommandUnresponsiveException, IOException {
         // now we delete the app we sync'ed
         try {
-            executeShellCommand("rm " + remoteFilePath, new NullOutputReceiver(), INSTALL_TIMEOUT);
+            executeShellCommand("rm " + remoteFilePath, NullOutputReceiver.getInstance(), INSTALL_TIMEOUT);
         } catch (IOException e) {
             Log.e(LOG_TAG, String.format("Failed to delete temporary package: %1$s", e.getMessage()));
             throw e;
index d78c501..2a58704 100644 (file)
@@ -1,19 +1,28 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ *  sdblib
  *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
  * 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
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
  */
-
 package org.tizen.sdblib;
 
 import java.io.IOException;
@@ -25,22 +34,24 @@ import java.nio.channels.SocketChannel;
 import java.util.ArrayList;
 
 import org.tizen.sdblib.Device.ArchInfoReceiver;
-import org.tizen.sdblib.IDevice.DeviceState;
-import org.tizen.sdblib.SdbHelper.SdbResponse;
+import org.tizen.sdblib.daemon.AbstractServer;
+import org.tizen.sdblib.daemon.ServerState;
+import org.tizen.sdblib.exception.TimeoutException;
+import org.tizen.sdblib.util.Log;
 
 /**
  * A Device monitor. This connects to the Smart Development Bridge and get device.
  */
-final class DeviceMonitor {
+class
+DeviceMonitor
+extends AbstractServer
+{
     private byte[] mLengthBuffer = new byte[4];
 
-    private boolean mQuit = false;
-
     private SmartDevelopmentBridge mServer;
 
     private SocketChannel mMainSdbConnection = null;
     private boolean mMonitoring = false;
-    private int mConnectionAttempt = 0;
     private int mRestartAttemptCount = 0;
     private boolean mInitialDeviceListDone = false;
 
@@ -55,45 +66,11 @@ final class DeviceMonitor {
      *            the running {@link SmartDevelopmentBridge}.
      */
     DeviceMonitor(SmartDevelopmentBridge server) {
+       super( "Devices Monitor" );
         mServer = server;
     }
 
     /**
-     * Starts the monitoring.
-     */
-    void start() {
-        Log.d("DeviceMonitor", "start monitoring");
-        new Thread("Device List Monitor") { //$NON-NLS-1$
-            @Override
-            public void run() {
-                deviceMonitorLoop();
-            }
-        }.start();
-    }
-
-    /**
-     * Stops the monitoring.
-     */
-    void stop() {
-        Log.d("DeviceMonitor", "stop monitoring");
-        mQuit = true;
-
-        // wake up the main loop thread by closing the main connection to sdb.
-        try {
-            if (mMainSdbConnection != null) {
-                mMainSdbConnection.close();
-            }
-        } catch (IOException e) {
-            Log.e("sdb", "close main sdb connection failed:" + e);
-        }
-
-        // wake up the secondary loop by closing the selector.
-        if (mSelector != null) {
-            mSelector.wakeup();
-        }
-    }
-
-    /**
      * Returns if the monitor is currently connected to the debug bridge server.
      * 
      * @return
@@ -102,10 +79,6 @@ final class DeviceMonitor {
         return mMonitoring;
     }
 
-    int getConnectionAttemptCount() {
-        return mConnectionAttempt;
-    }
-
     int getRestartAttemptCount() {
         return mRestartAttemptCount;
     }
@@ -127,56 +100,9 @@ final class DeviceMonitor {
         return mServer;
     }
 
-    /**
-     * Monitors the devices. This connects to the Debug Bridge
-     */
-    private void deviceMonitorLoop() {
-        do {
-            try {
-                if (mMainSdbConnection == null) {
-                    Log.d("DeviceMonitor", "opening sdb connection");
-                    mMainSdbConnection = openSdbConnection();
-                    if (mMainSdbConnection == null) {
-                        Log.d("DeviceMonitor", "start sdb");
-                        if (mServer.startSdb() == false) {
-                            mRestartAttemptCount++;
-                            Log.e("DeviceMonitor", "sdb restart attempts: " + mRestartAttemptCount);
-                        }
-                        waitABit();
-                    } else {
-                        Log.d("DeviceMonitor", "connected to sdb for device monitoring");
-                    }
-                }
-
-                if (mMainSdbConnection != null && mMonitoring == false) {
-                    mMonitoring = sendDeviceListMonitoringRequest();
-                }
-
-                if (mMonitoring) {
-                    // read the length of the incoming message
-                    int length = readLength(mMainSdbConnection, mLengthBuffer);
-
-                    if (length >= 0) {
-                        // read the incoming message
-                        processIncomingDeviceData(length);
-
-                        // flag the fact that we have build the list at least
-                        // once.
-                        mInitialDeviceListDone = true;
-                    }
-                }
-            } catch (AsynchronousCloseException ace) {
-                // this happens because of a call to Quit. We do nothing, and the loop will break.
-            } catch (TimeoutException ioe) {
-                handleExpectioninMonitorLoop(ioe);
-            } catch (IOException ioe) {
-                handleExpectioninMonitorLoop(ioe);
-            }
-        } while (mQuit == false);
-    }
-
     private void handleExpectioninMonitorLoop(Exception e) {
-        if (mQuit == false) {
+       if ( isState( ServerState.Running ) )
+       {
             if (e instanceof TimeoutException) {
                 Log.e("DeviceMonitor", "sdb connection Error: timeout");
             } else {
@@ -213,16 +139,13 @@ final class DeviceMonitor {
     private SocketChannel openSdbConnection() {
         Log.d("DeviceMonitor", "connecting to sdb for Device List Monitoring...");
 
-        SocketChannel sdbChannel = null;
         try {
-            sdbChannel = SocketChannel.open(SmartDevelopmentBridge.getSocketAddress());
-            mServer.setStarted(true);
-            sdbChannel.socket().setTcpNoDelay(true);
-        } catch (IOException e) {
-            Log.e("DeviceMonitor", "Failed to open socket channel");
+               return SmartDevelopmentBridge.getBridge().openChannel();
+        } catch (IOException e)        {
+            Log.e("DeviceMonitor", "Failed to open socket channel" );
+            Log.e("DeviceMonitor", e );
         }
-
-        return sdbChannel;
+        return null;
     }
 
     /**
@@ -292,7 +215,7 @@ final class DeviceMonitor {
     private void updateDevices(ArrayList<Device> newList) {
         // because we are going to call mServer.deviceDisconnected which will acquire this lock
         // we lock it first, so that the SmartDevelopmentBridge lock is always locked first.
-        synchronized (SmartDevelopmentBridge.getLock()) {
+//        synchronized (SmartDevelopmentBridge.getLock()) {
             // array to store the devices that must be queried for information.
             // it's important to not do it inside the synchronized loop as this could block
             // the whole workspace (this lock is acquired during build too).
@@ -364,7 +287,7 @@ final class DeviceMonitor {
                     }
                 }
             }
-        }
+//        }
         newList.clear();
     }
 
@@ -426,4 +349,76 @@ final class DeviceMonitor {
         return null;
     }
 
+       @Override
+    protected void initialize() throws Exception
+    {
+        Log.d("DeviceMonitor", "start monitoring");
+    }
+
+       @Override
+    protected void process() throws Exception
+    {
+               try {
+                       if (mMainSdbConnection == null) {
+                               Log.d("DeviceMonitor", "opening sdb connection");
+                               mMainSdbConnection = openSdbConnection();
+                               if (mMainSdbConnection == null) {
+                                       Log.d("DeviceMonitor", "start sdb");
+                                       if (mServer.startSdb() == false) {
+                                               mRestartAttemptCount++;
+                                               Log.e("DeviceMonitor", "sdb restart attempts: " + mRestartAttemptCount);
+                                       }
+                                       waitABit();
+                               } else {
+                                       Log.d("DeviceMonitor", "connected to sdb for device monitoring");
+                               }
+                       }
+
+                       if (mMainSdbConnection != null && mMonitoring == false) {
+                               mMonitoring = sendDeviceListMonitoringRequest();
+                       }
+
+                       if (mMonitoring) {
+                               // read the length of the incoming message
+                               int length = readLength(mMainSdbConnection, mLengthBuffer);
+
+                               if (length >= 0) {
+                                       // read the incoming message
+                                       processIncomingDeviceData(length);
+
+                                       // flag the fact that we have build the list at least
+                                       // once.
+                                       mInitialDeviceListDone = true;
+                               }
+                       }
+               } catch (AsynchronousCloseException ace) {
+                       // this happens because of a call to Quit. We do nothing, and the loop will break.
+               } catch (TimeoutException ioe) {
+                       handleExpectioninMonitorLoop(ioe);
+               } catch (IOException ioe) {
+                       handleExpectioninMonitorLoop(ioe);
+               }
+    }
+
+       @Override
+    protected void terminate()
+    {
+        Log.d("DeviceMonitor", "stop monitoring");
+        
+        // wake up the main loop thread by closing the main connection to sdb.
+        try {
+            if (mMainSdbConnection != null) {
+                mMainSdbConnection.close();
+            }
+        } catch (IOException e) {
+            Log.e("sdb", "close main sdb connection failed:" + e);
+        }
+
+        // wake up the secondary loop by closing the selector.
+        if (mSelector != null) {
+            mSelector.wakeup();
+        }
+
+    }
+
 }
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/DeviceState.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/DeviceState.java
new file mode 100644 (file)
index 0000000..58481a0
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib;\r
+\r
+\r
+/**\r
+ * The state of a device.\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+public enum\r
+DeviceState\r
+{\r
+    /**\r
+     * Offline state\r
+     */\r
+    OFFLINE("offline"), //$NON-NLS-1$\r
+    \r
+    /**\r
+     * Online\r
+     */\r
+    ONLINE("device"); //$NON-NLS-1$\r
+\r
+    /**\r
+     * State name\r
+     */\r
+    private String state;\r
+\r
+    /**\r
+     * Constructor with state name\r
+     * \r
+     * @param state state name\r
+     */\r
+    DeviceState(\r
+       final String state\r
+    )\r
+    {\r
+       this.state = state;\r
+    }\r
+    \r
+\r
+    /**\r
+     * Returns a {@link DeviceState} from the string returned by <code>sdb devices</code>.\r
+     *\r
+     * @param state the device state.\r
+     * @return a {@link DeviceState} object or <code>null</code> if the state is unknown.\r
+     */\r
+    public static\r
+    DeviceState\r
+    getState(\r
+       final String state\r
+    )\r
+    {\r
+        for ( final DeviceState deviceState : values() )\r
+        {\r
+            if ( deviceState.state.equals( state ) )\r
+            {\r
+                return deviceState;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/IDebugBridgeChangeListener.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/IDebugBridgeChangeListener.java
new file mode 100644 (file)
index 0000000..ecbf1e7
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib;\r
+\r
+/**\r
+ * IDebugBridgeChangeListener\r
+ * \r
+ * Classes which implement this interface provide a method that deals\r
+ * with {@link SmartDevelopmentBridge} changes.\r
+ * @author yoonki.park<park.yoonki@gmail.com>\r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+public interface\r
+IDebugBridgeChangeListener\r
+{\r
+    /**\r
+     * Sent when a new {@link SmartDevelopmentBridge} is connected.\r
+     * <p/>\r
+     * This is sent from a non UI thread.\r
+     * @param bridge the new {@link SmartDevelopmentBridge} object.\r
+     */\r
+    void bridgeChanged( SmartDevelopmentBridge bridge );\r
+\r
+}\r
index 9241e78..7e37c12 100755 (executable)
@@ -18,12 +18,18 @@ package org.tizen.sdblib;
 
 import java.io.IOException;
 
+import org.tizen.sdblib.exception.SdbCommandRejectedException;
+import org.tizen.sdblib.exception.ShellCommandUnresponsiveException;
+import org.tizen.sdblib.exception.TimeoutException;
+import org.tizen.sdblib.service.FileListingService;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.util.Preferences;
+import org.tizen.sdblib.util.SdbShellProcess;
+
 /**
  *  A Device. It can be a physical device or an emulator.
  */
 public interface IDevice {
-    /** Serial number of the first connected emulator. */
-    String FIRST_EMULATOR_SN = "emulator-26100"; //$NON-NLS-1$
     /** Device change bit mask: {@link DeviceState} change. */
     int CHANGE_STATE = 0x0001;
     /** Device change bit mask: {@link Client} list change. */
@@ -31,55 +37,7 @@ public interface IDevice {
     /** Device change bit mask: build info change. */
     int CHANGE_BUILD_INFO = 0x0004;
     
-    /**
-     * The architecture of a device.
-     * Returns {@link Arch#X86} or {@link Arch#ARM} about device architecture.
-     */
-    public static enum Arch{
-        X86("86"),
-        ARM("arm");
-
-        private String arch;
 
-        Arch(String arch)
-        {
-            this.arch = arch;
-        }
-
-        public String getArch()
-        {
-            return arch;
-        }
-    }
-
-    /**
-     * The state of a device.
-     */
-    public static enum DeviceState {
-        OFFLINE("offline"), //$NON-NLS-1$
-        ONLINE("device"); //$NON-NLS-1$
-
-        private String mState;
-
-        DeviceState(String state) {
-            mState = state;
-        }
-
-        /**
-         * Returns a {@link DeviceState} from the string returned by <code>sdb devices</code>.
-         *
-         * @param state the device state.
-         * @return a {@link DeviceState} object or <code>null</code> if the state is unknown.
-         */
-        public static DeviceState getState(String state) {
-            for (DeviceState deviceState : values()) {
-                if (deviceState.mState.equals(state)) {
-                    return deviceState;
-                }
-            }
-            return null;
-        }
-    }
 
     /**
      * Returns the serial number of the device.
@@ -91,6 +49,13 @@ public interface IDevice {
      */
     String getDeviceName();
 
+    /**
+     * Return the state of the device
+     * 
+     * @return state of the device
+     * 
+     * @see DeviceState
+     */
     DeviceState getState();
 
     /**
@@ -106,6 +71,7 @@ public interface IDevice {
     boolean isEmulator();
     
     /**
+     * Returns architecture of the device
      * Returns {@link Arch} about device architecture.
      */
     Arch getArch();
@@ -158,7 +124,7 @@ public interface IDevice {
      *
      * @see SdbShellProcess
      */
-    public Process executeShellCommand(String command, boolean prompt) throws IOException;
+    Process executeShellCommand(String command, boolean prompt) throws IOException;
     /**
      * Executes a shell command on the device, and sends the result to a <var>receiver</var>
      * <p/>This is similar to calling
@@ -174,7 +140,7 @@ public interface IDevice {
      * @throws IOException in case of I/O error on the connection.
      *
      * @see #executeShellCommand(String, IShellOutputReceiver, int)
-     * @see SdbPreferences#getTimeOut()
+     * @see Preferences#getTimeOut()
      */
     void executeShellCommand(String command, IShellOutputReceiver receiver)
             throws TimeoutException, SdbCommandRejectedException, ShellCommandUnresponsiveException,
@@ -205,7 +171,7 @@ public interface IDevice {
      *            for a period longer than <var>maxTimeToOutputResponse</var>.
      * @throws IOException in case of I/O error on the connection.
      *
-     * @see SdbPreferences#getTimeOut()
+     * @see Preferences#getTimeOut()
      */
     void executeShellCommand(String command, IShellOutputReceiver receiver,
             int maxTimeToOutputResponse)
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/IDeviceChangeListener.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/IDeviceChangeListener.java
new file mode 100644 (file)
index 0000000..f8f2a4e
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib;\r
+\r
+/**\r
+ * Interface to monitor following device's events\r
+ * <ul>\r
+ * <li>device addition</li>\r
+ * <li>device deletion</li>\r
+ * <li>device changes</li>\r
+ * </ul>\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+public interface\r
+IDeviceChangeListener\r
+{\r
+    /**\r
+     * Sent when the a device is connected to the {@link SmartDevelopmentBridge}.\r
+     * <p/>\r
+     * This is sent from a non UI thread.\r
+     * \r
+     * @param device the new device.\r
+     */\r
+    void onConnected( IDevice device );\r
+\r
+    /**\r
+     * Sent when the a device is connected to the {@link SmartDevelopmentBridge}.\r
+     * <p/>\r
+     * This is sent from a non UI thread.\r
+     * \r
+     * @param device the new device.\r
+     */\r
+    void onDisconnected(IDevice device);\r
+\r
+    /**\r
+     * Sent when a device data changed, or when clients are started/terminated on the device.\r
+     * <p/>\r
+     * This is sent from a non UI thread.\r
+     * @param device the device that was updated.\r
+     * @param changeMask the mask describing what changed. It can contain any of the following\r
+     * values: {@link IDevice#CHANGE_BUILD_INFO}, {@link IDevice#CHANGE_STATE},\r
+     * {@link IDevice#CHANGE_CLIENT_LIST}\r
+     */\r
+    void onChanged(IDevice device, int changeMask);\r
+}\r
index 4df697e..af69f57 100755 (executable)
@@ -1,44 +1,48 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ *  sdblib
  *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
  * 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
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
  */
-
 package org.tizen.sdblib;
 
+import java.io.Flushable;
+
 /**
- * Classes which implement this interface provide methods that deal with out from a remote shell
- * command on a device/emulator.
+ * IShellOutputReceiver
+ * 
+ * Interface to handle shells output
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
  */
-public interface IShellOutputReceiver {
-    /**
-     * Called every time some new data is available.
-     * @param data The new data.
-     * @param offset The offset at which the new data starts.
-     * @param length The length of the new data.
-     */
-    void addOutput(byte[] data, int offset, int length);
-
-    /**
-     * Called at the end of the process execution (unless the process was
-     * canceled). This allows the receiver to terminate and flush whatever
-     * data was not yet processed.
-     */
-    void flush();
+public interface
+IShellOutputReceiver
+extends Appendable, Flushable
+{
 
     /**
-     * Cancel method to stop the execution of the remote shell command.
-     * @return true to cancel the execution of the command.
+     * Check if the executioin of the shell command stop
+     * 
+     * @return true if the execution stop
      */
     boolean isCancelled();
 };
index 234a935..bb118aa 100755 (executable)
@@ -18,6 +18,8 @@ package org.tizen.sdblib;
 
 import java.security.InvalidParameterException;
 
+import org.tizen.sdblib.util.ArrayHelper;
+
 /**
  * Receiver able to provide low level parsing for device-side log services.
  */
@@ -95,7 +97,7 @@ public final class LogReceiver {
      * of {@link LogEntry} objects.
      * @param listener the listener to receive new log entries.
      */
-    public LogReceiver(ILogListener listener) {
+    private LogReceiver(ILogListener listener) {
         mListener = listener;
     }
     
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/MultiLineReceiver.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/MultiLineReceiver.java
deleted file mode 100755 (executable)
index 8a844d6..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 org.tizen.sdblib;
-
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-
-/**
- * Base implementation of {@link IShellOutputReceiver}, that takes the raw data
- * coming from the socket, and convert it into {@link String} objects.
- * <p/>
- * Additionally, it splits the string by lines.
- * <p/>
- * Classes extending it must implement {@link #processNewLines(String[])} which
- * receives new parsed lines as they become available.
- */
-public abstract class MultiLineReceiver implements IShellOutputReceiver {
-
-       private String OUTPUT_DECODING = "UTF-8";
-       private boolean mTrimLines = true;
-
-       /** unfinished message line, stored for next packet */
-       private String mUnfinishedLine = null;
-
-       private final ArrayList<String> mArray = new ArrayList<String>();
-
-       /**
-        * Set the trim lines flag.
-        * 
-        * @param trim
-        *            hether the lines are trimmed, or not.
-        */
-       public void setTrimLine(boolean trim) {
-               mTrimLines = trim;
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see com.samsung.sdblib.sdb.IShellOutputReceiver#addOutput( byte[], int,
-        * int)
-        */
-       public final void addOutput(byte[] data, int offset, int length) {
-               if (isCancelled() == false) {
-                       String s = null;
-                       try {
-                               s = new String(data, offset, length, OUTPUT_DECODING); //$NON-NLS-1$
-
-                       } catch (UnsupportedEncodingException e) {
-                               // normal encoding didn't work, try the default one
-                               s = new String(data, offset, length);
-                       }
-
-                       // ok we've got a string
-                       if (s != null) {
-                               // if we had an unfinished line we add it.
-                               if (mUnfinishedLine != null) {
-                                       s = mUnfinishedLine + s;
-                                       mUnfinishedLine = null;
-                               }
-
-                               // now we split the lines
-                               mArray.clear();
-                               int start = 0;
-                               do {
-                                       int index = s.indexOf("\r\n", start); //$NON-NLS-1$
-
-                                       // if \r\n was not found, this is an unfinished line
-                                       // and we store it to be processed for the next packet
-                                       if (index == -1) {
-                                               mUnfinishedLine = s.substring(start);
-                                               break;
-                                       }
-
-                                       // so we found a \r\n;
-                                       // extract the line
-                                       String line = s.substring(start, index);
-                                       if (mTrimLines) {
-                                               line = line.trim();
-                                       }
-                                       mArray.add(line);
-
-                                       // move start to after the \r\n we found
-                                       start = index + 2;
-                               } while (true);
-
-                               if (mArray.size() > 0) {
-                                       // at this point we've split all the lines.
-                                       // make the array
-                                       String[] lines = mArray.toArray(new String[mArray.size()]);
-
-                                       // send it for final processing
-                                       processNewLines(lines);
-                               }
-                       }
-               }
-               else
-               {
-                   Log.d("sdb", "process cancelled");
-               }
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see com.samsung.sdblib.sdb.IShellOutputReceiver#flush()
-        */
-       public final void flush() {
-               if (mUnfinishedLine != null && !mUnfinishedLine.isEmpty()) {
-                       processNewLines(new String[] { mUnfinishedLine });
-               }
-
-               done();
-       }
-
-       /**
-        * Terminates the process. This is called after the last lines have been
-        * through {@link #processNewLines(String[])}.
-        */
-       public void done() {
-               Log.d("sdb", "process done");
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see com.samsung.sdblib.sdb.IShellOutputReceiver#isCancelled()
-        */
-       public boolean isCancelled() {
-               return false;
-       }
-       
-       /**
-        * 
-        */
-       public String[] getLines() {
-           return mArray.toArray(new String[mArray.size()]);
-       }
-
-       /**
-        * Called when new lines are being received by the remote process.
-        * <p/>
-        * It is guaranteed that the lines are complete when they are given to this
-        * method.
-        * 
-        * @param lines
-        *            The array containing the new lines.
-        */
-       public abstract void processNewLines(String[] lines);
-}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/NullOutputReceiver.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/NullOutputReceiver.java
deleted file mode 100644 (file)
index 1c30a82..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 org.tizen.sdblib;
-
-/**
- * Implementation of {@link IShellOutputReceiver} that does nothing.
- * <p/>This can be used to execute a remote shell command when the output is not needed.
- */
-public final class NullOutputReceiver implements IShellOutputReceiver {
-
-    private static NullOutputReceiver sReceiver = new NullOutputReceiver();
-
-    public static IShellOutputReceiver getReceiver() {
-        return sReceiver;
-    }
-
-    /* (non-Javadoc)
-     * @see com.samsung.sdblib.sdb.IShellOutputReceiver#addOutput(byte[], int, int)
-     */
-    public void addOutput(byte[] data, int offset, int length) {
-    }
-
-    /* (non-Javadoc)
-     * @see com.samsung.sdblib.sdb.IShellOutputReceiver#flush()
-     */
-    public void flush() {
-    }
-
-    /* (non-Javadoc)
-     * @see com.samsung.sdblib.sdb.IShellOutputReceiver#isCancelled()
-     */
-    public boolean isCancelled() {
-        return false;
-    }
-
-}
index 60bb4df..7c70618 100644 (file)
 
 package org.tizen.sdblib;
 
+import static org.tizen.sdblib.util.IOUtil.tryClose;
+
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+
+import org.tizen.sdblib.exception.SdbCommandRejectedException;
+import org.tizen.sdblib.exception.ShellCommandUnresponsiveException;
+import org.tizen.sdblib.exception.TimeoutException;
+import org.tizen.sdblib.util.Log;
+import org.tizen.sdblib.util.Preferences;
 
 /**
  * Helper class to handle requests and connections to sdb.
@@ -29,33 +39,27 @@ import java.nio.channels.SocketChannel;
  * <p/>This currently uses spin-wait non-blocking I/O. A Selector would be more efficient,
  * but seems like overkill for what we're doing here.
  */
-final class SdbHelper {
+public class SdbHelper {
 
     // public static final long kOkay = 0x59414b4fL;
     // public static final long kFail = 0x4c494146L;
 
-    static final int WAIT_TIME = 5; // spin-wait sleep, in ms
+    public static final int WAIT_TIME = 5; // spin-wait sleep, in ms
 
-    static final String DEFAULT_ENCODING = "ISO-8859-1"; //$NON-NLS-1$
-    static final String UTF_ENCODING = "UTF-8"; 
+    public static final String DEFAULT_ENCODING = "ISO-8859-1"; //$NON-NLS-1$
+    public static final String UTF_ENCODING = "UTF-8"; 
+    public static final String OUTPUT_DECODING = "UTF-8";
+    
+       public static final Charset UTF_CHARSET = Charset.forName( UTF_ENCODING );
 
-    /** do not instantiate */
-    private SdbHelper() {
-    }
 
-    /**
-     * Response from SDB.
-     */
-    static class SdbResponse {
-        public SdbResponse() {
-            message = "";
-        }
 
-        public boolean okay; // first 4 bytes in response were "OKAY"?
 
-        public String message; // diagnostic string if #okay is false
+    /** do not instantiate */
+    private SdbHelper() {
     }
 
+
     /**
      * Create and connect a new pass-through socket, from the host to a port on
      * the device.
@@ -183,8 +187,7 @@ final class SdbHelper {
      * we're on the host side connecting into the device, "addrStr" should be
      * null.
      */
-    static byte[] formSdbRequest(String req) {
-
+    public static byte[] formSdbRequest(String req) {
         byte [] result;
         byte [] reqByte;
         byte [] lengthByte;
@@ -216,7 +219,7 @@ final class SdbHelper {
      * @throws TimeoutException in case of timeout on the connection.
      * @throws IOException in case of I/O error on the connection.
      */
-    static SdbResponse readSdbResponse(SocketChannel chan, boolean readDiagString)
+    public static SdbResponse readSdbResponse(SocketChannel chan, boolean readDiagString)
             throws TimeoutException, IOException {
 
         SdbResponse resp = new SdbResponse();
@@ -346,9 +349,9 @@ final class SdbHelper {
      *            for a period longer than <var>maxTimeToOutputResponse</var>.
      * @throws IOException in case of I/O error on the connection.
      *
-     * @see SdbPreferences#getTimeOut()
+     * @see Preferences#getTimeOut()
      */
-    static void executeRemoteCommand(InetSocketAddress sdbSockAddr,
+    static void executeRemoteCommand(SmartDevelopmentBridge sdb,
             String command, IDevice device, IShellOutputReceiver rcvr, int maxTimeToOutputResponse)
             throws TimeoutException, SdbCommandRejectedException, ShellCommandUnresponsiveException,
             IOException {
@@ -356,8 +359,7 @@ final class SdbHelper {
 
         SocketChannel sdbChan = null;
         try {
-            sdbChan = SocketChannel.open(sdbSockAddr);
-            sdbChan.configureBlocking(false);
+            sdbChan = sdb.openChannel();
 
             // if the device is not -1, then we first tell sdb we're looking to
             // talk
@@ -376,6 +378,7 @@ final class SdbHelper {
             byte[] data = new byte[16384];
             ByteBuffer buf = ByteBuffer.wrap(data);
             int timeToResponseCount = 0;
+            final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
             while (true) {
                 int count;
 
@@ -408,15 +411,21 @@ final class SdbHelper {
 
                     // send data to receiver if present
                     if (rcvr != null) {
-                        rcvr.addOutput(buf.array(), buf.arrayOffset(), buf.position());
+                       byteOut.write( buf.array(), buf.arrayOffset(), buf.position() );
+                       try
+                        {
+                               rcvr.append( new String( byteOut.toByteArray(), OUTPUT_DECODING ) );
+                        } catch (Exception e)
+                        {
+                               rcvr.append( new String( byteOut.toByteArray() ) );
+                        }
+                       byteOut.reset();
                     }
                     buf.rewind();
                 }
             }
         } finally {
-            if (sdbChan != null) {
-                sdbChan.close();
-            }
+               tryClose( sdbChan );
             Log.v("sdb", "execute: returning");
         }
     }
@@ -425,22 +434,22 @@ final class SdbHelper {
      * Runs the Event log service on the {@link Device}, and provides its output to the
      * {@link LogReceiver}.
      * <p/>This call is blocking until {@link LogReceiver#isCancelled()} returns true.
-     * @param sdbSockAddr the socket address to connect to sdb
+     * @param sdb the socket address to connect to sdb
      * @param device the Device on which to run the service
      * @param rcvr the {@link LogReceiver} to receive the log output
      * @throws TimeoutException in case of timeout on the connection.
      * @throws SdbCommandRejectedException if sdb rejects the command
      * @throws IOException in case of I/O error on the connection.
      */
-    public static void runEventLogService(InetSocketAddress sdbSockAddr, Device device,
+    public static void runEventLogService( final SmartDevelopmentBridge sdb, Device device,
             LogReceiver rcvr) throws TimeoutException, SdbCommandRejectedException, IOException {
-        runLogService(sdbSockAddr, device, "events", rcvr); //$NON-NLS-1$
+        runLogService(sdb, device, "events", rcvr); //$NON-NLS-1$
     }
 
     /**
      * Runs a log service on the {@link Device}, and provides its output to the {@link LogReceiver}.
      * <p/>This call is blocking until {@link LogReceiver#isCancelled()} returns true.
-     * @param sdbSockAddr the socket address to connect to sdb
+     * @param sdb the socket address to connect to sdb
      * @param device the Device on which to run the service
      * @param logName the name of the log file to output
      * @param rcvr the {@link LogReceiver} to receive the log output
@@ -448,13 +457,12 @@ final class SdbHelper {
      * @throws SdbCommandRejectedException if sdb rejects the command
      * @throws IOException in case of I/O error on the connection.
      */
-    public static void runLogService(InetSocketAddress sdbSockAddr, Device device, String logName,
+    public static void runLogService( SmartDevelopmentBridge sdb, Device device, String logName,
             LogReceiver rcvr) throws TimeoutException, SdbCommandRejectedException, IOException {
         SocketChannel sdbChan = null;
 
         try {
-            sdbChan = SocketChannel.open(sdbSockAddr);
-            sdbChan.configureBlocking(false);
+            sdbChan = sdb.openChannel();
 
             // if the device is not -1, then we first tell sdb we're looking to talk
             // to a specific device
@@ -493,6 +501,7 @@ final class SdbHelper {
                 }
             }
         } finally {
+               tryClose( sdbChan );
             if (sdbChan != null) {
                 sdbChan.close();
             }
@@ -501,7 +510,7 @@ final class SdbHelper {
 
     /**
      * Creates a port forwarding between a local and a remote port.
-     * @param sdbSockAddr the socket address to connect to sdb
+     * @param sdb the socket address to connect to sdb
      * @param device the device on which to do the port fowarding
      * @param localPort the local port to forward
      * @param remotePort the remote port.
@@ -509,13 +518,12 @@ final class SdbHelper {
      * @throws SdbCommandRejectedException if sdb rejects the command
      * @throws IOException in case of I/O error on the connection.
      */
-    public static void createForward(InetSocketAddress sdbSockAddr, Device device, int localPort,
+    public static void createForward( SmartDevelopmentBridge sdb, Device device, int localPort,
             int remotePort) throws TimeoutException, SdbCommandRejectedException, IOException {
 
         SocketChannel sdbChan = null;
         try {
-            sdbChan = SocketChannel.open(sdbSockAddr);
-            sdbChan.configureBlocking(false);
+            sdbChan = sdb.openChannel();
 
             byte[] request = formSdbRequest(String.format(
                     "host-serial:%1$s:forward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
@@ -529,15 +537,13 @@ final class SdbHelper {
                 throw new SdbCommandRejectedException(resp.message);
             }
         } finally {
-            if (sdbChan != null) {
-                sdbChan.close();
-            }
+               tryClose( sdbChan );
         }
     }
 
     /**
      * Remove a port forwarding between a local and a remote port.
-     * @param sdbSockAddr the socket address to connect to sdb
+     * @param sdb the socket address to connect to sdb
      * @param device the device on which to remove the port fowarding
      * @param localPort the local port of the forward
      * @param remotePort the remote port.
@@ -545,13 +551,12 @@ final class SdbHelper {
      * @throws SdbCommandRejectedException if sdb rejects the command
      * @throws IOException in case of I/O error on the connection.
      */
-    public static void removeForward(InetSocketAddress sdbSockAddr, Device device, int localPort,
+    public static void removeForward( SmartDevelopmentBridge sdb, Device device, int localPort,
             int remotePort) throws TimeoutException, SdbCommandRejectedException, IOException {
 
         SocketChannel sdbChan = null;
         try {
-            sdbChan = SocketChannel.open(sdbSockAddr);
-            sdbChan.configureBlocking(false);
+            sdbChan = sdb.openChannel();
 
             byte[] request = formSdbRequest(String.format(
                     "host-serial:%1$s:killforward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
@@ -565,6 +570,7 @@ final class SdbHelper {
                 throw new SdbCommandRejectedException(resp.message);
             }
         } finally {
+               tryClose( sdbChan );
             if (sdbChan != null) {
                 sdbChan.close();
             }
@@ -605,7 +611,7 @@ final class SdbHelper {
      * @throws IOException in case of I/O error on the connection.
      */
     static void read(SocketChannel chan, byte[] data) throws TimeoutException, IOException {
-        read(chan, data, -1, SdbPreferences.getTimeOut());
+        read(chan, data, -1, Preferences.getTimeOut());
     }
 
     /**
@@ -621,7 +627,7 @@ final class SdbHelper {
      * @param length the length to read or -1 to fill the data buffer completely
      * @param timeout The timeout value. A timeout of zero means "wait forever".
      */
-    static void read(SocketChannel chan, byte[] data, int length, int timeout)
+    public static void read(SocketChannel chan, byte[] data, int length, int timeout)
             throws TimeoutException, IOException {
         ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
         int numWaits = 0;
@@ -659,8 +665,8 @@ final class SdbHelper {
      * @throws TimeoutException in case of timeout on the connection.
      * @throws IOException in case of I/O error on the connection.
      */
-    static void write(SocketChannel chan, byte[] data) throws TimeoutException, IOException {
-        write(chan, data, -1, SdbPreferences.getTimeOut());
+    public static void write(SocketChannel chan, byte[] data) throws TimeoutException, IOException {
+        write(chan, data, -1, Preferences.getTimeOut());
     }
 
     /**
@@ -674,7 +680,7 @@ final class SdbHelper {
      * @throws TimeoutException in case of timeout on the connection.
      * @throws IOException in case of I/O error on the connection.
      */
-    static void write(SocketChannel chan, byte[] data, int length, int timeout)
+    public static void write(SocketChannel chan, byte[] data, int length, int timeout)
             throws TimeoutException, IOException {
         ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
         int numWaits = 0;
@@ -713,7 +719,7 @@ final class SdbHelper {
      * @throws SdbCommandRejectedException if sdb rejects the command
      * @throws IOException in case of I/O error on the connection.
      */
-    static void setDevice(SocketChannel sdbChan, IDevice device)
+    public static void setDevice(SocketChannel sdbChan, IDevice device)
             throws TimeoutException, SdbCommandRejectedException, IOException {
         // if the device is not -1, then we first tell sdb we're looking to talk
         // to a specific device
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/SdbResponse.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/SdbResponse.java
new file mode 100644 (file)
index 0000000..3fc4a7d
--- /dev/null
@@ -0,0 +1,11 @@
+package org.tizen.sdblib;\r
+\r
+/**\r
+ * Response from SDB.\r
+ */\r
+public class SdbResponse\r
+{\r
+       public boolean okay; // first 4 bytes in response were "OKAY"?\r
+       \r
+       public String message = ""; // diagnostic string if #okay is false\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/SdbShellProcess.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/SdbShellProcess.java
deleted file mode 100755 (executable)
index 87e052e..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Common
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: 
- * Hyunsik Noh <hyunsik.noh@samsung.com>
- * BonYong Lee <bonyong.lee@samsung.com>
- * Kangho Kim <kh5325.kim@samsung.com>
- * 
- * 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.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-package org.tizen.sdblib;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-
-import org.tizen.sdblib.Log;
-
-public class SdbShellProcess extends Process {
-
-       public Process process = null;
-       public BufferedWriter bw = null;
-       
-       public SdbShellProcess(Process process, String command) {
-               this.process = process;
-               bw = new BufferedWriter(new OutputStreamWriter(this.process.getOutputStream()));
-               try {
-                       bw.write(command + ";exit");
-                       bw.newLine();
-                       bw.flush();
-               } catch (IOException e) {
-                       Log.e("sdb", "buffer write failed:" +  e);
-               }
-       }
-       
-       private void interrupt() {
-               char c = 0x03; //standard code representing "Ctrl-C" sequence
-               try {
-                       bw.write(c);
-                       bw.flush();
-                       Thread.sleep(250); // wait for terminate
-               } catch (IOException e) {
-                       Log.e("sdb", "buffer write failed:" +  e);
-               } catch (InterruptedException e) {
-                       Log.e("sdb", "buffer interruted:" +  e);
-               } finally {
-                       try {
-                               bw.close();
-                       } catch (IOException e) {
-                               Log.e("sdb", "close failed:" +  e);
-                       }
-               }
-       }
-       
-       @Override
-       public void destroy() {
-               interrupt();
-               try {
-                       process.exitValue();
-               }
-               catch ( final IllegalThreadStateException e )
-               {
-                       process.destroy();
-               }
-       }
-
-       @Override
-       public int exitValue() {
-               return process.exitValue();
-       }
-
-       @Override
-       public InputStream getErrorStream() {
-               return process.getErrorStream();
-       }
-
-       @Override
-       public InputStream getInputStream() {
-               return process.getInputStream();
-       }
-
-       @Override
-       public OutputStream getOutputStream() {
-               return process.getOutputStream();
-       }
-
-       @Override
-       public int waitFor() throws InterruptedException {
-               return process.waitFor();
-       }
-}
index e5a8030..05f4d14 100644 (file)
 
 package org.tizen.sdblib;
 
+import static org.tizen.sdblib.SmartDevelopmentBridgetConstants.SDB_DEFAULT_HOST;
+import static org.tizen.sdblib.SmartDevelopmentBridgetConstants.SDB_DEFAULT_PORT;
+import static org.tizen.sdblib.SmartDevelopmentBridgetConstants.SERVER_PORT_ENV_VAR;
+import static org.tizen.sdblib.util.ParsingUtil.parseInt;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
+import java.nio.channels.SocketChannel;
 import java.security.InvalidParameterException;
 import java.util.ArrayList;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+import org.tizen.sdblib.exception.ServerException;
+import org.tizen.sdblib.util.Log;
+import org.tizen.sdblib.util.StreamGobbler;
+
 /**
  * A connection to the host-side smart development bridge (sdb)
  * <p/>This is the central point to communicate with any devices, emulators, or the applications
@@ -34,18 +44,12 @@ import java.util.concurrent.locks.ReentrantLock;
  * <p/><b>{@link #init(boolean)} must be called before anything is done.</b>
  */
 public final class SmartDevelopmentBridge {
-    private final static String SDB = "sdb"; //$NON-NLS-1$
-    private final static String SDBLIB = "sdblib"; //$NON-NLS-1$
-    private final static String SERVER_PORT_ENV_VAR = "SDB_SERVER_PORT"; //$NON-NLS-1$
-
-    // Where to find the SDB bridge.
-    final static String SDB_HOST = "127.0.0.1"; //$NON-NLS-1$
-    final static int SDB_PORT = 26099;
+    private final static String TAG_SDB = "sdb"; //$NON-NLS-1$
+    private final static String TAG_SDBLIB = "sdblib"; //$NON-NLS-1$
 
-    private static InetAddress sHostAddr;
-    private static InetSocketAddress sSocketAddr;
+    private static InetSocketAddress socketAddr;
 
-    private static SmartDevelopmentBridge sThis;
+    private static SmartDevelopmentBridge instance;
 
     /** Full path to sdb. */
     private String mSdbOsLocation = null;
@@ -53,7 +57,7 @@ public final class SmartDevelopmentBridge {
     protected Lock lock = new ReentrantLock();
     private boolean mStarted = false;
 
-    private DeviceMonitor mDeviceMonitor;
+    private DeviceMonitor deviceMonitor;
 
     private final static ArrayList<IDebugBridgeChangeListener> sBridgeListeners =
         new ArrayList<IDebugBridgeChangeListener>();
@@ -64,53 +68,6 @@ public final class SmartDevelopmentBridge {
     private static final Object sLock = sBridgeListeners;
 
     /**
-     * Classes which implement this interface provide a method that deals
-     * with {@link SmartDevelopmentBridge} changes.
-     */
-    public interface IDebugBridgeChangeListener {
-        /**
-         * Sent when a new {@link SmartDevelopmentBridge} is connected.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param bridge the new {@link SmartDevelopmentBridge} object.
-         */
-        public void bridgeChanged(SmartDevelopmentBridge bridge);
-    }
-
-    /**
-     * Classes which implement this interface provide methods that deal
-     * with {@link IDevice} addition, deletion, and changes.
-     */
-    public interface IDeviceChangeListener {
-        /**
-         * Sent when the a device is connected to the {@link SmartDevelopmentBridge}.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param device the new device.
-         */
-        public void deviceConnected(IDevice device);
-
-        /**
-         * Sent when the a device is connected to the {@link SmartDevelopmentBridge}.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param device the new device.
-         */
-        public void deviceDisconnected(IDevice device);
-
-        /**
-         * Sent when a device data changed, or when clients are started/terminated on the device.
-         * <p/>
-         * This is sent from a non UI thread.
-         * @param device the device that was updated.
-         * @param changeMask the mask describing what changed. It can contain any of the following
-         * values: {@link IDevice#CHANGE_BUILD_INFO}, {@link IDevice#CHANGE_STATE},
-         * {@link IDevice#CHANGE_CLIENT_LIST}
-         */
-        public void deviceChanged(IDevice device, int changeMask);
-    }
-
-    /**
      * Initializes the <code>sdb</code> library.
      * <p/>This must be called once <b>before</b> any call to
      * {@link #createBridge(String, boolean)}.
@@ -135,9 +92,42 @@ public final class SmartDevelopmentBridge {
      * @see SmartDevelopmentBridge#createBridge(String, boolean)
      * @see SdbPreferences
      */
-    public static void init() {
+    protected static void init() {
         // Determine port and instantiate socket address.
-        initsdbSocketAddr();
+        try {
+               int sdbPort = parseInt( System.getenv( SERVER_PORT_ENV_VAR ), SDB_DEFAULT_PORT );
+
+               if ( sdbPort <= 0)
+               {
+                       throw new IllegalArgumentException( "env var " + SERVER_PORT_ENV_VAR + ": must be >=0, got " + System.getenv(SERVER_PORT_ENV_VAR) ); //$NON-NLS-1$
+               }
+               socketAddr = new InetSocketAddress( InetAddress.getByName( SDB_DEFAULT_HOST ), sdbPort );
+        }
+        catch ( final NumberFormatException ex )
+        {
+               throw new IllegalArgumentException( "env var " + SERVER_PORT_ENV_VAR + ": illegal value '" + System.getenv(SERVER_PORT_ENV_VAR) + "'" ); //$NON-NLS-1$
+        }
+        catch ( final SecurityException ex )
+        {
+               // A security manager has been installed that doesn't allow access to env vars.
+               // So an environment variable might have been set, but we can't tell.
+               // Let's log a warning and continue with SDB's default port.
+               // The issue is that sdb would be started (by the forked process having access
+               // to the env vars) on the desired port, but within this process, we can't figure out
+               // what that port is. However, a security manager not granting access to env vars
+               // but allowing to fork is a rare and interesting configuration, so the right
+               // thing seems to be to continue using the default port, as forking is likely to
+               // fail later on in the scenario of the security manager.
+               Log.w(TAG_SDBLIB,
+                       "No access to env variables allowed by current security manager. " //$NON-NLS-1$
+                       + "If you've set SDB_SERVER_PORT: it's being ignored."); //$NON-NLS-1$
+
+        }
+        catch ( final UnknownHostException e )
+        {
+               // localhost should always be known.
+               Log.e("sdb", "init socket failed:" +  e);
+        }
     }
 
     /**
@@ -145,63 +135,20 @@ public final class SmartDevelopmentBridge {
      */
     public static void terminate() {
         // kill the monitoring services
-        if (sThis != null && sThis.mDeviceMonitor != null) {
-            sThis.mDeviceMonitor.stop();
-            sThis.mDeviceMonitor = null;
+        if (instance != null && instance.deviceMonitor != null) {
+            instance.deviceMonitor.down();
+            instance.deviceMonitor = null;
         }
     }
 
-    /**
-     * Returns the socket address of the SDB server on the host.
-     */
-    public static InetSocketAddress getSocketAddress() {
-        return sSocketAddr;
-    }
-
-    /**
-     * Creates a {@link SmartDevelopmentBridge} that is not linked to any particular executable.
-     * <p/>This bridge will expect sdb to be running. It will not be able to start/stop
-     * sdb.
-     * <p/>If a bridge has already been started, it is directly returned with no changes (similar
-     * to calling {@link #getBridge()}).
-     * @return a connected bridge.
-     */
-    public static SmartDevelopmentBridge createBridge() {
-        synchronized (sLock) {
-            if (sThis != null) {
-                return sThis;
-            }
-
-            try {
-                sThis = new SmartDevelopmentBridge();
-                sThis.start();
-            } catch (InvalidParameterException e) {
-                sThis = null;
-            }
-
-            // because the listeners could remove themselves from the list while processing
-            // their event callback, we make a copy of the list and iterate on it instead of
-            // the main list.
-            // This mostly happens when the application quits.
-            IDebugBridgeChangeListener[] listenersCopy = sBridgeListeners.toArray(
-                    new IDebugBridgeChangeListener[sBridgeListeners.size()]);
-
-            // notify the listeners of the change
-            for (IDebugBridgeChangeListener listener : listenersCopy) {
-                // we attempt to catch any exception so that a bad listener doesn't kill our
-                // thread
-                try {
-                    listener.bridgeChanged(sThis);
-                } catch (Exception e) {
-                    Log.e(SDBLIB, e);
-                }
-            }
-
-            return sThis;
-        }
+    public SocketChannel openChannel() throws IOException
+    {
+       final SocketChannel channel = SocketChannel.open( socketAddr );
+       channel.configureBlocking( false );
+       
+       return channel;
     }
 
-
     /**
      * Creates a new debug bridge from the location of the command line tool.
      * <p/>
@@ -214,19 +161,20 @@ public final class SmartDevelopmentBridge {
      * @throws Exception
      */
     public static SmartDevelopmentBridge createBridge(String osLocation, boolean forceNewBridge){
+       init();
         synchronized (sLock) {
-            if (sThis != null) {
-                if (sThis.mSdbOsLocation != null && sThis.mSdbOsLocation.equals(osLocation) &&
+            if (instance != null) {
+                if (instance.mSdbOsLocation != null && instance.mSdbOsLocation.equals(osLocation) &&
                         forceNewBridge == false) {
-                    return sThis;
+                    return instance;
                 } else {
                     // stop the current server
-                    sThis.stop();
+                    instance.stop();
                 }
             }
 
-            sThis = new SmartDevelopmentBridge(osLocation);
-            sThis.start();
+            instance = new SmartDevelopmentBridge(osLocation);
+            instance.start();
 
             // because the listeners could remove themselves from the list while processing
             // their event callback, we make a copy of the list and iterate on it instead of
@@ -240,13 +188,13 @@ public final class SmartDevelopmentBridge {
                 // we attempt to catch any exception so that a bad listener doesn't kill our
                 // thread
                 try {
-                    listener.bridgeChanged(sThis);
+                    listener.bridgeChanged(instance);
                 } catch (Exception e) {
-                    Log.e(SDBLIB, e);
+                    Log.e(TAG_SDBLIB, e);
                 }
             }
 
-            return sThis;
+            return instance;
         }
     }
 
@@ -254,7 +202,7 @@ public final class SmartDevelopmentBridge {
      * Returns the current debug bridge. Can be <code>null</code> if none were created.
      */
     public static SmartDevelopmentBridge getBridge() {
-        return sThis;
+        return instance;
     }
 
     public String getSdbOsLocation() {
@@ -269,9 +217,9 @@ public final class SmartDevelopmentBridge {
      */
     public static void disconnectBridge() {
         synchronized (sLock) {
-            if (sThis != null) {
-                sThis.stop();
-                sThis = null;
+            if (instance != null) {
+                instance.stop();
+                instance = null;
 
                 // because the listeners could remove themselves from the list while processing
                 // their event callback, we make a copy of the list and iterate on it instead of
@@ -285,9 +233,9 @@ public final class SmartDevelopmentBridge {
                     // we attempt to catch any exception so that a bad listener doesn't kill our
                     // thread
                     try {
-                        listener.bridgeChanged(sThis);
+                        listener.bridgeChanged(instance);
                     } catch (Exception e) {
-                        Log.e(SDBLIB, e);
+                        Log.e(TAG_SDBLIB, e);
                     }
                 }
             }
@@ -304,13 +252,13 @@ public final class SmartDevelopmentBridge {
         synchronized (sLock) {
             if (sBridgeListeners.contains(listener) == false) {
                 sBridgeListeners.add(listener);
-                if (sThis != null) {
+                if (instance != null) {
                     // we attempt to catch any exception so that a bad listener doesn't kill our
                     // thread
                     try {
-                        listener.bridgeChanged(sThis);
+                        listener.bridgeChanged(instance);
                     } catch (Exception e) {
-                        Log.e(SDBLIB, e);
+                        Log.e(TAG_SDBLIB, e);
                     }
                 }
             }
@@ -357,7 +305,7 @@ public final class SmartDevelopmentBridge {
                     {
                         if(device.isOnline())
                         {
-                            listener.deviceConnected(device);
+                            listener.onConnected(device);
                         }
                     }
                 }
@@ -383,8 +331,8 @@ public final class SmartDevelopmentBridge {
      */
     public IDevice[] getDevices() {
         synchronized (sLock) {
-            if (mDeviceMonitor != null) {
-                return mDeviceMonitor.getDevices();
+            if (deviceMonitor != null) {
+                return deviceMonitor.getDevices();
             }
         }
 
@@ -401,8 +349,8 @@ public final class SmartDevelopmentBridge {
      * {@link IDeviceChangeListener} object.
      */
     public boolean hasInitialDeviceList() {
-        if (mDeviceMonitor != null) {
-            return mDeviceMonitor.hasInitialDeviceList();
+        if (deviceMonitor != null) {
+            return deviceMonitor.hasInitialDeviceList();
         }
 
         return false;
@@ -412,30 +360,19 @@ public final class SmartDevelopmentBridge {
      * Returns whether the {@link SmartDevelopmentBridge} object is still connected to the sdb daemon.
      */
     public boolean isConnected() {
-        if (mDeviceMonitor != null) {
-            return mDeviceMonitor.isMonitoring();
+        if (deviceMonitor != null) {
+            return deviceMonitor.isMonitoring();
         }
         return false;
     }
 
     /**
-     * Returns the number of times the {@link SmartDevelopmentBridge} object attempted to connect
-     * to the sdb daemon.
-     */
-    public int getConnectionAttemptCount() {
-        if (mDeviceMonitor != null) {
-            return mDeviceMonitor.getConnectionAttemptCount();
-        }
-        return -1;
-    }
-
-    /**
      * Returns the number of times the {@link SmartDevelopmentBridge} object attempted to restart
      * the sdb daemon.
      */
     public int getRestartAttemptCount() {
-        if (mDeviceMonitor != null) {
-            return mDeviceMonitor.getRestartAttemptCount();
+        if (deviceMonitor != null) {
+            return deviceMonitor.getRestartAttemptCount();
         }
         return -1;
     }
@@ -464,11 +401,18 @@ public final class SmartDevelopmentBridge {
      */
     boolean start() {
 
-        // now that the bridge is connected, we start the underlying services.
-        mDeviceMonitor = new DeviceMonitor(this);
-        mDeviceMonitor.start();
+        try
+        {
+               // now that the bridge is connected, we start the underlying services.
+               deviceMonitor = new DeviceMonitor(this);
+               deviceMonitor.boot();
 
-        return true;
+               return true;
+        } catch (ServerException e)
+        {
+               e.printStackTrace();
+               return false;
+        }
     }
 
    /**
@@ -482,8 +426,8 @@ public final class SmartDevelopmentBridge {
         }
 
         // kill the monitoring services
-        mDeviceMonitor.stop();
-        mDeviceMonitor = null;
+        deviceMonitor.down();
+        deviceMonitor = null;
 
         if (stopSdb() == false) {
             return false;
@@ -499,7 +443,7 @@ public final class SmartDevelopmentBridge {
      */
     public boolean restart() {
         if (mSdbOsLocation == null) {
-            Log.e(SDB,
+            Log.e(TAG_SDB,
                     "Cannot restart sdb when SmartDevelopmentBridge is created without the location of sdb."); //$NON-NLS-1$
             return false;
         }
@@ -509,9 +453,8 @@ public final class SmartDevelopmentBridge {
 
             boolean restart = startSdb();
 
-            if (restart && mDeviceMonitor == null) {
-                mDeviceMonitor = new DeviceMonitor(this);
-                mDeviceMonitor.start();
+            if (restart && deviceMonitor == null) {
+               start();
             }
 
             return restart;
@@ -547,9 +490,9 @@ public final class SmartDevelopmentBridge {
             // we attempt to catch any exception so that a bad listener doesn't kill our
             // thread
             try {
-                listener.deviceConnected(device);
+                listener.onConnected(device);
             } catch (Exception e) {
-                Log.e(SDBLIB, e);
+                Log.e(TAG_SDBLIB, e);
             }
         }
     }
@@ -583,9 +526,9 @@ public final class SmartDevelopmentBridge {
             // we attempt to catch any exception so that a bad listener doesn't kill our
             // thread
             try {
-                listener.deviceDisconnected(device);
+                listener.onDisconnected(device);
             } catch (Exception e) {
-                Log.e(SDBLIB, e);
+                Log.e(TAG_SDBLIB, e);
             }
         }
     }
@@ -619,9 +562,9 @@ public final class SmartDevelopmentBridge {
             // we attempt to catch any exception so that a bad listener doesn't kill our
             // thread
             try {
-                listener.deviceChanged(device, changeMask);
+                listener.onChanged(device, changeMask);
             } catch (Exception e) {
-                Log.e(SDBLIB, e);
+                Log.e(TAG_SDBLIB, e);
             }
         }
     }
@@ -630,7 +573,7 @@ public final class SmartDevelopmentBridge {
      * Returns the {@link DeviceMonitor} object.
      */
     DeviceMonitor getDeviceMonitor() {
-        return mDeviceMonitor;
+        return deviceMonitor;
     }
 
     /**
@@ -639,7 +582,7 @@ public final class SmartDevelopmentBridge {
      */
     synchronized boolean startSdb() {
         if (mSdbOsLocation == null) {
-            Log.e(SDB,
+            Log.e(TAG_SDB,
                 "Cannot start sdb when SmartDevelopmentBridge is created without the location of sdb."); //$NON-NLS-1$
             return false;
         }
@@ -651,31 +594,28 @@ public final class SmartDevelopmentBridge {
             String[] command = new String[2];
             command[0] = mSdbOsLocation;
             command[1] = "start-server"; //$NON-NLS-1$
-            Log.d(SDBLIB,
+            Log.d(TAG_SDBLIB,
                     String.format("launching '%1$s %2$s' to ensure SDB is running.", //$NON-NLS-1$
                     mSdbOsLocation, command[1]));
             proc = Runtime.getRuntime().exec(command);
 
-            ArrayList<String> errorOutput = new ArrayList<String>();
-            ArrayList<String> stdOutput = new ArrayList<String>();
-            status = grabProcessOutput(proc, errorOutput, stdOutput,
-                    false /* waitForReaders */);
+            status = grabProcessOutput( proc );
 
         } catch (IOException ioe) {
-            Log.d(SDBLIB, "unable to run 'sdb': " + ioe.getMessage()); //$NON-NLS-1$
+            Log.d(TAG_SDBLIB, "unable to run 'sdb': " + ioe.getMessage()); //$NON-NLS-1$
             // we'll return false;
         } catch (InterruptedException ie) {
-            Log.d(SDBLIB, "unable to run 'sdb': " + ie.getMessage()); //$NON-NLS-1$
+            Log.d(TAG_SDBLIB, "unable to run 'sdb': " + ie.getMessage()); //$NON-NLS-1$
             // we'll return false;
         }
 
         if (status != 0) {
-            Log.w(SDBLIB,
+            Log.w(TAG_SDBLIB,
                     "'sdb start-server' failed -- run manually if necessary"); //$NON-NLS-1$
             return false;
         }
 
-        Log.d(SDBLIB, "'sdb start-server' succeeded"); //$NON-NLS-1$
+        Log.d(TAG_SDBLIB, "'sdb start-server' succeeded"); //$NON-NLS-1$
         setStarted(true);
         return true;
     }
@@ -686,7 +626,7 @@ public final class SmartDevelopmentBridge {
      */
     private synchronized boolean stopSdb() {
         if (mSdbOsLocation == null) {
-            Log.e(SDB,
+            Log.e(TAG_SDB,
                 "Cannot stop sdb when SmartDevelopmentBridge is created without the location of sdb."); //$NON-NLS-1$
             return false;
         }
@@ -710,12 +650,12 @@ public final class SmartDevelopmentBridge {
         }
 
         if (status != 0) {
-            Log.w(SDBLIB,
+            Log.w(TAG_SDBLIB,
                     "'sdb kill-server' failed -- run manually if necessary"); //$NON-NLS-1$
             return false;
         }
 
-        Log.d(SDBLIB, "'sdb kill-server' succeeded"); //$NON-NLS-1$
+        Log.d(TAG_SDBLIB, "'sdb kill-server' succeeded"); //$NON-NLS-1$
         setStarted(false);
         return true;
     }
@@ -731,11 +671,8 @@ public final class SmartDevelopmentBridge {
      * @return the process return code.
      * @throws InterruptedException
      */
-    private int grabProcessOutput(final Process process, final ArrayList<String> errorOutput,
-            final ArrayList<String> stdOutput, boolean waitforReaders)
+    private int grabProcessOutput(final Process process )
             throws InterruptedException {
-        assert errorOutput != null;
-        assert stdOutput != null;
         // read the lines as they come. if null is returned, it's
         // because the process finished
         Thread t1 = new Thread("SdbReadThread1") { //$NON-NLS-1$
@@ -749,8 +686,7 @@ public final class SmartDevelopmentBridge {
                     while (true) {
                         String line = errReader.readLine();
                         if (line != null) {
-                            Log.e(SDB, line);
-                            errorOutput.add(line);
+                            Log.e(TAG_SDB, line);
                         } else {
                             break;
                         }
@@ -778,8 +714,7 @@ public final class SmartDevelopmentBridge {
                     while (true) {
                         String line = outReader.readLine();
                         if (line != null) {
-                            Log.d(SDB, line);
-                            stdOutput.add(line);
+                            Log.d(TAG_SDB, line);
                         } else {
                             break;
                         }
@@ -800,20 +735,6 @@ public final class SmartDevelopmentBridge {
         t1.start();
         t2.start();
 
-        // it looks like on windows process#waitFor() can return
-        // before the thread have filled the arrays, so we wait for both threads and the
-        // process itself.
-        if (waitforReaders) {
-            try {
-                t1.join();
-            } catch (InterruptedException e) {
-            }
-            try {
-                t2.join();
-            } catch (InterruptedException e) {
-            }
-        }
-
         // get the return code from the process
         return process.waitFor();
     }
@@ -828,73 +749,6 @@ public final class SmartDevelopmentBridge {
         return sLock;
     }
 
-    /**
-     * Instantiates sSocketAddr with the address of the host's sdb process.
-     */
-    private static void initsdbSocketAddr() {
-        try {
-            int sdb_port = determineAndValidateSdbPort();
-            sHostAddr = InetAddress.getByName(SDB_HOST);
-            sSocketAddr = new InetSocketAddress(sHostAddr, sdb_port);
-        } catch (UnknownHostException e) {
-            // localhost should always be known.
-               Log.e("sdb", "init socket failed:" +  e);
-        }
-    }
-
-    /**
-     * Determines port where SDB is expected by looking at an env variable.
-     * <p/>
-     * The value for the environment variable SDB_SERVER_PORT is validated,
-     * IllegalArgumentException is thrown on illegal values.
-     * <p/>
-     * @return The port number where the host's sdb should be expected or started.
-     * @throws IllegalArgumentException if SDB_SERVER_PORT has a non-numeric value.
-     */
-    private static int determineAndValidateSdbPort() {
-        String sdb_env_var;
-        int result = SDB_PORT;
-        try {
-            sdb_env_var = System.getenv(SERVER_PORT_ENV_VAR);
-
-            if (sdb_env_var != null) {
-                sdb_env_var = sdb_env_var.trim();
-            }
-
-            if (sdb_env_var != null && sdb_env_var.length() > 0) {
-                // C tools (sdb, emulator) accept hex and octal port numbers, so need to accept
-                // them too.
-                result = Integer.decode(sdb_env_var);
-
-                if (result <= 0) {
-                    String errMsg = "env var " + SERVER_PORT_ENV_VAR //$NON-NLS-1$
-                            + ": must be >=0, got " //$NON-NLS-1$
-                            + System.getenv(SERVER_PORT_ENV_VAR);
-                    throw new IllegalArgumentException(errMsg);
-                }
-            }
-        } catch (NumberFormatException nfEx) {
-            String errMsg = "env var " + SERVER_PORT_ENV_VAR //$NON-NLS-1$
-                    + ": illegal value '" //$NON-NLS-1$
-                    + System.getenv(SERVER_PORT_ENV_VAR) + "'"; //$NON-NLS-1$
-            throw new IllegalArgumentException(errMsg);
-        } catch (SecurityException secEx) {
-            // A security manager has been installed that doesn't allow access to env vars.
-            // So an environment variable might have been set, but we can't tell.
-            // Let's log a warning and continue with SDB's default port.
-            // The issue is that sdb would be started (by the forked process having access
-            // to the env vars) on the desired port, but within this process, we can't figure out
-            // what that port is. However, a security manager not granting access to env vars
-            // but allowing to fork is a rare and interesting configuration, so the right
-            // thing seems to be to continue using the default port, as forking is likely to
-            // fail later on in the scenario of the security manager.
-            Log.w(SDBLIB,
-                    "No access to env variables allowed by current security manager. " //$NON-NLS-1$
-                    + "If you've set SDB_SERVER_PORT: it's being ignored."); //$NON-NLS-1$
-        }
-        return result;
-    }
-    
     public void waitforStart()
     {
         while(!getStarted())
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/SmartDevelopmentBridgetConstants.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/SmartDevelopmentBridgetConstants.java
new file mode 100644 (file)
index 0000000..bbf6c6f
--- /dev/null
@@ -0,0 +1,12 @@
+package org.tizen.sdblib;\r
+\r
+public class\r
+SmartDevelopmentBridgetConstants\r
+{\r
+    public final static String SERVER_PORT_ENV_VAR = "SDB_SERVER_PORT"; //$NON-NLS-1$\r
+\r
+    // Where to find the SDB bridge.\r
+    public final static String SDB_DEFAULT_HOST = "127.0.0.1"; //$NON-NLS-1$\r
+    public final static int SDB_DEFAULT_PORT = 26099;\r
+\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/AbstractServer.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/AbstractServer.java
new file mode 100644 (file)
index 0000000..66fc186
--- /dev/null
@@ -0,0 +1,333 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib.daemon;\r
+\r
+import java.util.concurrent.locks.Lock;\r
+import java.util.concurrent.locks.ReentrantLock;\r
+\r
+import org.tizen.sdblib.exception.ServerException;\r
+import org.tizen.sdblib.util.Log;\r
+\r
+/**\r
+ * <p>\r
+ * AbstractServer\r
+ * \r
+ * abstract common class for {@link Server}\r
+ * </p>\r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ *\r
+ */\r
+abstract public class\r
+AbstractServer\r
+implements Server, Runnable\r
+{\r
+    /**\r
+     * {@link Thread} to use in this server\r
+     */\r
+    protected Thread thread = null;\r
+    \r
+    /**\r
+     * lock for #state\r
+     */\r
+    protected Lock lock = new ReentrantLock();\r
+    \r
+    /**\r
+     * server state\r
+     * @see ServerState\r
+     */\r
+    protected ServerState state = ServerState.Terminated;\r
+    \r
+    /**\r
+     * Server name to use thread name\r
+     */\r
+    protected final String name;\r
+    \r
+    /**\r
+     * default constructor\r
+     */\r
+    public AbstractServer()\r
+    {\r
+        this( null );\r
+    }\r
+    \r
+    /**\r
+     * constructor with name\r
+     * \r
+     * @param name server name\r
+     */\r
+    public\r
+    AbstractServer(\r
+        final String name\r
+    )\r
+    {\r
+        this.name = name;\r
+    }\r
+    \r
+    /**\r
+     * return server name\r
+     * @return server name\r
+     * \r
+     * @see #name\r
+     */\r
+    public\r
+    String\r
+    getName()\r
+    {\r
+        return name;\r
+    }\r
+    \r
+    /**\r
+     * return server status\r
+     * @return server status\r
+     * \r
+     * @see #state\r
+     * @see ServerState\r
+     */\r
+    public\r
+    ServerState\r
+    getStatus()\r
+    {\r
+        lock.lock();\r
+        try\r
+        {\r
+            return this.state;\r
+        }\r
+        finally\r
+        {\r
+            lock.unlock();\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Change server state\r
+     * \r
+     * @param state server state\r
+     * \r
+     * @see #state\r
+     * @see ServerState\r
+     */\r
+    protected\r
+    void\r
+    setStatus(\r
+        final ServerState state\r
+    )\r
+    {\r
+        lock.lock();\r
+        try\r
+        {\r
+            this.state = state;\r
+        }\r
+        finally\r
+        {\r
+            lock.unlock();\r
+            synchronized ( this )\r
+            {\r
+                notifyAll();\r
+            }\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * check server state is one of <code>states</code>\r
+     * \r
+     * @param states state candidates to check\r
+     * \r
+     * @return boolean value if server state is one of <code>states</code>\r
+     */\r
+    public\r
+    boolean\r
+    isState(\r
+        final ServerState... states\r
+    )\r
+    {\r
+        lock.lock();\r
+        try\r
+        {\r
+            for ( final ServerState state : states )\r
+            {\r
+                if ( this.state.equals( state ) )\r
+                {\r
+                    return true;\r
+                }\r
+            }\r
+            return false;\r
+        }\r
+        finally\r
+        {\r
+            lock.unlock();\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * wait until server state become one of <code>states</code>\r
+     *  \r
+     * @param states server states\r
+     */\r
+    public\r
+    void\r
+    waitState(\r
+        final ServerState... states\r
+    )\r
+    {\r
+        while ( !isState( states ) ) {\r
+            try\r
+            {\r
+                synchronized ( this )\r
+                {\r
+                    wait();\r
+                }\r
+            } catch ( final InterruptedException e )\r
+            {\r
+            }\r
+        }\r
+    }\r
+    \r
+    \r
+\r
+    /* (non-Javadoc)\r
+     * @see java.lang.Runnable#run()\r
+     */\r
+    @Override\r
+    public\r
+    void\r
+    run()\r
+    {\r
+        if ( isState( ServerState.Halting ) )\r
+        {\r
+            setStatus( ServerState.Terminated );\r
+            return ;\r
+        }\r
+        try\r
+        {\r
+            initialize();\r
+            \r
+            lock.lock();\r
+            try\r
+            {\r
+                if ( isState( ServerState.Halting ) )\r
+                {\r
+                    return ;\r
+                }\r
+                setStatus( ServerState.Running );\r
+            }\r
+            finally\r
+            {\r
+                lock.unlock();\r
+            }\r
+            while ( !isState( ServerState.Halting ) )\r
+            {\r
+                process();\r
+            }\r
+        }\r
+        catch ( Exception e )\r
+        {\r
+            Log.e( "Error occurred:", e );\r
+        }\r
+        finally\r
+        {\r
+            terminate();\r
+            setStatus( ServerState.Terminated );\r
+        }\r
+        \r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.tizen.common.daemon.Server#boot()\r
+     */\r
+    @Override\r
+    public\r
+    void\r
+    boot()\r
+    throws ServerException\r
+    {\r
+        lock.lock();\r
+        try\r
+        {\r
+            if ( !isState( ServerState.Terminated ) )\r
+            {\r
+                throw new IllegalStateException();\r
+            }\r
+            \r
+            final String name = getName();\r
+            if ( null == name )\r
+            {\r
+                thread = new Thread( this );\r
+            }\r
+            else \r
+            {\r
+                thread = new Thread( this, name );\r
+            }\r
+            thread.start();\r
+            setStatus( ServerState.Initializing );\r
+        }\r
+        finally\r
+        {\r
+            lock.unlock();\r
+        }\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.tizen.common.daemon.Server#down()\r
+     */\r
+    @Override\r
+    public\r
+    void\r
+    down()\r
+    {\r
+        lock.lock();\r
+        try\r
+        {\r
+            if ( isState( ServerState.Terminated, ServerState.Halting ) ) {\r
+                throw new IllegalStateException();\r
+            }\r
+            setStatus( ServerState.Halting );\r
+        }\r
+        finally\r
+        {\r
+            lock.unlock();\r
+        }\r
+        \r
+    }\r
+\r
+    /**\r
+     * Server initialization process\r
+     * \r
+     * @throws Exception If exception is occurred\r
+     */\r
+    abstract protected void initialize() throws Exception;\r
+    \r
+    /**\r
+     * Unit process of main job\r
+     * \r
+     * @throws Exception If exception is occurred\r
+     */\r
+    abstract protected void process() throws Exception;\r
+    \r
+    /**\r
+     * Server clean-up process\r
+     */\r
+    abstract protected void terminate();\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/Server.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/Server.java
new file mode 100644 (file)
index 0000000..b050eb1
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib.daemon;\r
+\r
+import org.tizen.sdblib.exception.ServerException;\r
+\r
+/**\r
+ * <p>\r
+ * Server\r
+ * \r
+ * Interface to daemon( thread )\r
+ *\r
+ * </p>\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+public interface\r
+Server\r
+{\r
+    /**\r
+     * boot daemon up\r
+     * \r
+     * @throws ServerException If process is failed\r
+     */\r
+    void boot() throws ServerException;\r
+    \r
+    /**\r
+     * shut daemon down\r
+     * @throws ServerException If process is failed\r
+     */\r
+    void down() throws ServerException;\r
+\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/ServerState.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/daemon/ServerState.java
new file mode 100644 (file)
index 0000000..1c1d24c
--- /dev/null
@@ -0,0 +1,64 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib.daemon;\r
+\r
+/**\r
+ * <p>\r
+ * ServerState\r
+ * \r
+ * State of {@link Server}\r
+ * <ul>\r
+ * <li>{@link #Terminated}</li>\r
+ * <li>{@link #Initializing}</li>\r
+ * <li>{@link #Running}</li>\r
+ * <li>{@link #Halting}</li>\r
+ * </p>\r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ *\r
+ */\r
+public enum ServerState\r
+{\r
+    /**\r
+     * Stopped state\r
+     */\r
+    Terminated,\r
+    \r
+    /**\r
+     * State to request boot\r
+     */\r
+    Initializing,\r
+    \r
+    /**\r
+     * State to run\r
+     */\r
+    Running,\r
+    \r
+    /**\r
+     * State to request down\r
+     */\r
+    Halting\r
+\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/exception/ServerException.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/exception/ServerException.java
new file mode 100644 (file)
index 0000000..e20bd7f
--- /dev/null
@@ -0,0 +1,97 @@
+/*\r
+ * Common\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib.exception;\r
+\r
+/**\r
+ * <p>\r
+ * ServerException\r
+ * \r
+ * Exception for server operation\r
+ *\r
+ * </p>\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+public class\r
+ServerException\r
+extends Exception\r
+{\r
+\r
+       /**\r
+     * uuid for serialization\r
+     */\r
+    private static final long serialVersionUID = 3662986092815719651L;\r
+    \r
+    /**\r
+     * Default constructor\r
+     */\r
+    public\r
+    ServerException()\r
+    {\r
+       super();\r
+    }\r
+\r
+    /**\r
+     * Constructor with exception message\r
+     * \r
+     * @param msg exception message\r
+     */\r
+    public\r
+    ServerException(\r
+       final String msg\r
+    )\r
+    {\r
+       super( msg );\r
+    }\r
+    \r
+    /**\r
+     * Constructor with cause\r
+     * \r
+     * @param cause cause of this exception\r
+     */\r
+    public\r
+    ServerException(\r
+       final Throwable cause\r
+    )\r
+    {\r
+       super( cause );\r
+    }\r
+    \r
+    /**\r
+     * Constructor with exception message and cuase\r
+     * \r
+     * @param msg exception message\r
+     * @param cause cause of this exception\r
+     */\r
+    public\r
+    ServerException(\r
+       final String msg,\r
+       final Throwable cause\r
+    )\r
+    {\r
+       super( msg, cause );\r
+    }\r
+    \r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/AbstractShellOutputReceiver.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/AbstractShellOutputReceiver.java
new file mode 100644 (file)
index 0000000..8927e7c
--- /dev/null
@@ -0,0 +1,103 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib.receiver;\r
+\r
+import java.io.IOException;\r
+\r
+import org.tizen.sdblib.IShellOutputReceiver;\r
+\r
+/**\r
+ * AbstractShellOutputReceiver\r
+ * \r
+ * Abstract class for {@link IShellOutputReceiver}\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+abstract public class\r
+AbstractShellOutputReceiver\r
+implements IShellOutputReceiver\r
+{\r
+\r
+       /* (non-Javadoc)\r
+        * @see java.lang.Appendable#append(java.lang.CharSequence)\r
+        */\r
+       @Override\r
+    public\r
+    Appendable\r
+    append(\r
+       final CharSequence csq\r
+    )\r
+    throws IOException\r
+    {\r
+               if ( null == csq )\r
+               {\r
+                       return this;\r
+               }\r
+           return append( csq, 0, csq.length() );\r
+    }\r
+\r
+       /* (non-Javadoc)\r
+        * @see java.lang.Appendable#append(java.lang.CharSequence, int, int)\r
+        */\r
+       @Override\r
+    public\r
+    Appendable\r
+    append(\r
+       final CharSequence csq,\r
+       final int start,\r
+       final int end\r
+    )\r
+    throws IOException\r
+    {\r
+               if ( null == csq )\r
+               {\r
+                       return this;\r
+               }\r
+               for ( int i = start ; i < end ; ++i )\r
+               {\r
+                       append( csq.charAt( i ) );\r
+               }\r
+           return this;\r
+    }\r
+\r
+       /* (non-Javadoc)\r
+        * @see java.io.Flushable#flush()\r
+        */\r
+       @Override\r
+    public void flush() throws IOException\r
+    {\r
+    }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.tizen.sdblib.IShellOutputReceiver#isCancelled()\r
+        */\r
+       @Override\r
+    public boolean isCancelled()\r
+    {\r
+           return false;\r
+    }\r
+\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/MultiLineReceiver.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/MultiLineReceiver.java
new file mode 100644 (file)
index 0000000..2239c6e
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.receiver;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.tizen.sdblib.IShellOutputReceiver;
+
+/**
+ * MultiLineReceiver
+ * 
+ * Input sequential {@link CharSequence}s and split by lines
+ * <p/>
+ * Classes extending it must implement {@link #processNewLines(String[])} which
+ * receives new parsed lines as they become available.
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+abstract public class
+MultiLineReceiver
+extends AbstractShellOutputReceiver
+implements IShellOutputReceiver
+{
+
+       /**
+        * Flag to trim line
+        */
+       protected boolean bTrimLines = true;
+
+       /**
+        * Line separation status - Normal
+        */
+       protected static final int ST_NORMAL = 0;
+       /**
+        * Line separation status - Meet \r
+        */
+       protected static final int ST_LINE_CANDIDATE = 1;
+       
+       /**
+        * Line separation status
+        */
+       protected int status = ST_NORMAL;
+
+       /**
+        * Buffered lines
+        */
+       private final ArrayList<String> lines = new ArrayList<String>();
+       
+       /**
+        * Unprocessed line
+        */
+       protected final StringBuilder buffer = new StringBuilder();
+       
+       /**
+        * Default constructor
+        */
+       public
+       MultiLineReceiver()
+       {
+               this( true );
+       }
+       
+       /**
+        * Constructor with trim lines flag
+        * 
+        * @param bTrimLines flag to trim lines
+        */
+       public
+       MultiLineReceiver(
+               final boolean bTrimLines
+       )
+       {
+               this.bTrimLines = bTrimLines;
+       }
+
+       /**
+        * Set the trim lines flag.
+        * 
+        * @param bTrimLines whether the lines are trimmed, or not.
+        */
+       public
+       void
+       setTrimLines(
+               final boolean bTrimLines
+       )
+       {
+               this.bTrimLines = bTrimLines;
+       }
+
+    /* (non-Javadoc)
+     * @see java.lang.Appendable#append(char)
+     */
+    public
+    Appendable
+    append(
+       final char c
+    )
+    throws IOException
+    {
+       if ( ST_NORMAL == status )
+       {
+               if ( '\r' == c ) {
+                       status = ST_LINE_CANDIDATE;
+               }
+               else
+               {
+                       buffer.append( c );
+               }
+       }
+       else if ( ST_LINE_CANDIDATE == status )
+       {
+               if ( '\n' == c )
+               {
+                       String line = buffer.toString();
+                       if ( bTrimLines )
+                       {
+                                       line = line.trim();
+                               }
+                       lines.add( line );
+                       buffer.delete( 0, buffer.length() );
+                       status = ST_NORMAL;
+               }
+               else if ( '\r' == c )
+               {
+                       buffer.append( '\r' );
+               }
+               else
+               {
+                       buffer.append( '\r' );
+                       buffer.append( c );
+                       status = ST_NORMAL;
+               }
+       }
+       return this;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.tizen.sdblib.receiver.AbstractShellOutputReceiver#append(java.lang.CharSequence, int, int)
+     */
+    public
+    Appendable
+    append(
+       final CharSequence csq,
+       final int start,
+       final int end
+    )
+    throws IOException
+    {
+       final Appendable ret = super.append( csq, start, end );
+       flush();
+       return ret;
+    }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.samsung.sdblib.sdb.IShellOutputReceiver#flush()
+        */
+       public final void flush()
+       {
+               if ( 0 < lines.size() )
+               {
+                       // at this point we've split all the lines.
+                       // make the array
+
+                       // send it for final processing
+                       processNewLines( this.lines.toArray(new String[this.lines.size()]) );
+                       this.lines.clear();
+                       
+               }
+       }
+
+       /**
+        * <p>
+        * Called when new lines are being received from external
+        * 
+        * It is guaranteed that the lines are complete when they are given to this
+        * method.
+        * 
+        * @param lines The array containing the new lines.
+        */
+       abstract public void processNewLines( String[] lines );
+}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/NullOutputReceiver.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/NullOutputReceiver.java
new file mode 100644 (file)
index 0000000..a673545
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.receiver;
+
+import java.io.IOException;
+
+import org.tizen.sdblib.IShellOutputReceiver;
+
+/**
+ * NullOutputReceiver
+ * 
+ * No operation object
+ * 
+ * This is used for flush buffer
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public final class
+NullOutputReceiver
+extends AbstractShellOutputReceiver
+implements IShellOutputReceiver
+{
+
+    /**
+     * Singleton object
+     */
+    protected static final NullOutputReceiver instance = new NullOutputReceiver();
+
+    /**
+     * Method to access singleton
+     * 
+     * @return {@link #instance}
+     */
+    public static IShellOutputReceiver getInstance()
+    {
+        return instance;
+    }
+    
+    /**
+     * Default constructor
+     * 
+     * Not recommend to create new instance
+     */
+    protected NullOutputReceiver()
+    {
+    }
+
+       /* (non-Javadoc)
+        * @see java.lang.Appendable#append(char)
+        */
+       @Override
+    public
+    Appendable
+    append(
+       final char c
+    )
+    throws IOException
+    {
+           return this;
+    }
+
+}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/service/CrashReportService.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/service/CrashReportService.java
new file mode 100644 (file)
index 0000000..69d6960
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.service;
+
+import static org.tizen.sdblib.SdbHelper.UTF_CHARSET;
+import static org.tizen.sdblib.util.IOUtil.tryClose;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+
+import org.tizen.sdblib.ICrashReportServiceListener;
+import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.IDeviceChangeListener;
+import org.tizen.sdblib.SdbHelper;
+import org.tizen.sdblib.SdbResponse;
+import org.tizen.sdblib.SmartDevelopmentBridge;
+import org.tizen.sdblib.daemon.AbstractServer;
+import org.tizen.sdblib.util.Log;
+import org.tizen.sdblib.util.Preferences;
+
+/**
+ * CrashReportService provides notification to all listeners when a cs file is created.
+ * 
+ *  <p/>It is needed to implement {@link ICSServiceListener} for getting the service.
+ *  
+ * @author yoonki.park<yoonki.park@samsung.com>
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+CrashReportService
+extends AbstractServer
+implements IDeviceChangeListener
+{
+    /**
+     * listeners
+     */
+    protected final LinkedHashSet<ICrashReportServiceListener> listeners = new LinkedHashSet<ICrashReportServiceListener>();
+    
+    /**
+     * Selector for channel
+     */
+    protected Selector selector = null;
+    
+    /**
+     * Default constructor
+     * 
+     * @throws IOException If can't open selector
+     */
+    public
+    CrashReportService()
+    {
+       super( "CS Report Service" );
+    }
+
+    /**
+     * Initializes report channels when Tizen device are connected right after
+     * launching IDE.
+     */
+    protected
+    void
+    initReportChannel()
+    {
+        final IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
+        for ( final IDevice device : devices )
+        {
+            if ( device.isOnline() )
+            {
+                registerReportChannel( device );
+            }
+        }
+    }
+
+    /**
+     * Registers a channel for given device.
+     * 
+     * @param device
+     */
+    protected
+    void
+    registerReportChannel(
+       final IDevice device
+    )
+    {
+
+        try {
+               final SocketChannel channel = SmartDevelopmentBridge.getBridge().openChannel();
+
+            SdbHelper.setDevice( channel, device );
+
+            byte[] request = SdbHelper.formSdbRequest("cs:");
+            SdbHelper.write(channel, request, -1, Preferences.getTimeOut());
+
+            SdbResponse resp = SdbHelper.readSdbResponse(channel, false);
+            System.out.println( resp.okay );
+
+            if (resp.okay == false) {
+                Log.e("sdb", "got unhappy response from sdb cs req: " + resp.message);
+                tryClose(channel);
+                return;
+            }
+            Log.i("sdb", "registering CS Report Service");
+            selector.wakeup();
+            channel.register(selector, SelectionKey.OP_READ, device);
+            Log.i("sdb", "registered CS Report Service");
+        } catch (IOException e) {
+               e.printStackTrace();
+            Log.e("sdb", "failed to open a socket channel");
+        }
+    }
+
+    /**
+     * Reads a cs file path from the given key, and send this path to all
+     * listener.
+     * 
+     * @param key
+     *            Selected key.
+     * @return
+     */
+    private
+    void
+    read(
+       final SelectionKey key
+    )
+    {
+        final SocketChannel sc = (SocketChannel) key.channel();
+        try
+        {
+            final ByteBuffer reply = ByteBuffer.allocate( 124 );
+
+            final int len = sc.read( reply );
+            Log.i( "sdb", "read byte :" + len );
+            if ( 0 < len )
+            {
+               reply.flip();
+               notifyAllListeners( (IDevice) key.attachment(), UTF_CHARSET.decode( reply ).toString() );
+            }
+        }
+        catch ( final IOException e )
+        {
+               key.cancel();
+               Log.e("sdb", "read failed :" + e);
+               tryClose( sc );
+        }
+    }
+
+    /* ICrashReportServiceListener */
+    /**
+     * Notifies all listeners cs file creation.
+     * 
+     * @param device device to be notified from
+     * @param path path of crash report
+     */
+    @SuppressWarnings("unchecked")
+    private
+    void
+    notifyAllListeners(
+       final IDevice device,
+       final String path
+    )
+    {
+       Log.i( "sdb", "cs file is created and notify from " + device.getSerialNumber() );
+        Collection<ICrashReportServiceListener> temp = null;
+        synchronized ( this ) {
+               temp = (Collection<ICrashReportServiceListener>) listeners.clone();
+        }
+        for ( final ICrashReportServiceListener listener : temp )
+        {
+               try {
+                       listener.fileCreated( device, path );
+               } catch (Exception e) {
+                       Log.e("sdb", "unexpected error occurred :" + e);
+               }
+        }
+    }
+
+    synchronized public
+    void
+    addCrashReportServiceListener(
+       final ICrashReportServiceListener listener
+    )
+    {
+       listeners.add(listener);
+    }
+
+    synchronized public
+    void
+    removeCrashReportServiceListener(
+       final ICrashReportServiceListener listener
+    )
+    {
+       listeners.remove(listener);
+    }
+
+    /* IDeviceChangeListener */
+    @Override
+    public
+    void
+    onConnected(
+       final IDevice device
+    )
+    {
+        if ( device.isOnline() )
+        {
+            Log.i("sdb", "welcome to new connection :" + device.getSerialNumber());
+            registerReportChannel(device);
+        }
+    }
+
+    @Override
+    public
+    void
+    onDisconnected(IDevice device)
+    {
+        Log.i("sdb", "bye!:" + device.getSerialNumber());
+    }
+
+    @Override
+    public
+    void
+    onChanged(
+       final IDevice device,
+       final int changeMask
+    )
+    {
+        if ( changeMask == 1 )
+        {
+            onConnected( device );
+        }
+    }
+
+    /* Server */
+       @Override
+    protected
+    void
+    initialize()
+    throws Exception
+    {
+        Log.i("sdb", "starting CS Report Service");
+        selector = Selector.open();
+        SmartDevelopmentBridge.addDeviceChangeListener( this );
+        initReportChannel(); // TODO : should moved to deviceConnected event
+    }
+
+       @Override
+    protected
+    void
+    process()
+    throws Exception
+    {
+               Log.d( "crashreport", "Wait any response" );
+        if (selector.select() <= 0) { //spin-wait sleep, in ms
+            return;
+        }
+        final Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
+        while ( iter.hasNext() )
+        {
+            final SelectionKey key = iter.next();
+            if ( key.isConnectable() )
+            {
+                final SocketChannel sc = (SocketChannel) key.channel();
+                if ( sc.isConnectionPending() )
+                {
+                    sc.finishConnect();
+                }
+            }
+            else if ( key.isReadable() )
+            {
+                read( key );
+            }
+            iter.remove();
+        }
+    }
+
+       @Override
+    protected
+    void
+    terminate()
+    {
+        SmartDevelopmentBridge.removeDeviceChangeListener(this);
+               tryClose( selector );
+    }
+}
\ No newline at end of file
@@ -1,20 +1,29 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ *  sdblib
  *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
  * 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
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
  */
-
-package org.tizen.sdblib;
+package org.tizen.sdblib.service;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -23,17 +32,25 @@ import java.util.HashMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.tizen.sdblib.Device;
+import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
+import org.tizen.sdblib.util.Log;
+
 /**
  * Provides {@link Device} side file listing service.
  * <p/>
  * To get an instance for a known {@link Device}, call
  * {@link Device#getFileListingService()}.
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
  */
-public final class FileListingService
+public class
+FileListingService
 {
 
-    /** Pattern to find filenames that match "*.apk" */
-    private final static Pattern sApkPattern = Pattern.compile(".*\\.apk", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+    /** Pattern to find filenames that match "*.tpk" */
+    private final static Pattern PKG_PATTERN = Pattern.compile(".*\\.apk", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
 
     private final static String PM_FULL_LISTING = "pm list packages -f"; //$NON-NLS-1$
 
@@ -411,7 +428,7 @@ public final class FileListingService
          */
         public boolean isAppFileName()
         {
-            Matcher m = sApkPattern.matcher(name);
+            Matcher m = PKG_PATTERN.matcher(name);
             return m.matches();
         }
 
@@ -731,8 +748,8 @@ public final class FileListingService
      * Classes which implement this interface provide a method that deals with
      * asynchronous result from <code>ls</code> command on the device.
      *
-     * @see FileListingService#getChildren(com.samsung.sdblib.FileListingService.FileEntry,
-     *      boolean, com.samsung.sdblib.FileListingService.IListingReceiver)
+     * @see FileListingService#getChildren(org.tizen.sdblib.service.samsung.sdblib.FileListingService.FileEntry,
+     *      boolean, org.tizen.sdblib.service.samsung.sdblib.FileListingService.IListingReceiver)
      */
     public interface IListingReceiver
     {
@@ -747,7 +764,7 @@ public final class FileListingService
      * @param device
      *            The Device the service is connected to.
      */
-    FileListingService(Device device)
+    public FileListingService(Device device)
     {
         mDevice = device;
     }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 97%
rename from org.tizen.common.sdblib/src/org/tizen/sdblib/SyncService.java
rename to org.tizen.common.sdblib/src/org/tizen/sdblib/service/SyncService.java
index cfa61b6..70bb0a4
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.tizen.sdblib;
+package org.tizen.sdblib.service;
 
 import java.io.Closeable;
 import java.io.File;
@@ -23,13 +23,20 @@ import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
 import java.nio.channels.SocketChannel;
 import java.util.ArrayList;
 
-import org.tizen.sdblib.FileListingService.FileEntry;
-import org.tizen.sdblib.SdbHelper.SdbResponse;
-import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.Device;
+import org.tizen.sdblib.SdbHelper;
+import org.tizen.sdblib.SdbResponse;
+import org.tizen.sdblib.SmartDevelopmentBridge;
+import org.tizen.sdblib.exception.SdbCommandRejectedException;
+import org.tizen.sdblib.exception.TimeoutException;
+import org.tizen.sdblib.service.FileListingService.FileEntry;
+import org.tizen.sdblib.service.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.util.ArrayHelper;
+import org.tizen.sdblib.util.Log;
+import org.tizen.sdblib.util.Preferences;
 
 
 /**
@@ -188,7 +195,7 @@ public final class SyncService implements Closeable {
         }
     }
 
-    private final InetSocketAddress mAddress;
+    private final SmartDevelopmentBridge sdb;
     private final Device mDevice;
     private SocketChannel mChannel;
 
@@ -202,8 +209,8 @@ public final class SyncService implements Closeable {
      * @param address The address to connect to
      * @param device the {@link Device} that the service connects to.
      */
-    SyncService(InetSocketAddress address, Device device) {
-        mAddress = address;
+    public SyncService( final SmartDevelopmentBridge sdb, Device device) {
+        this.sdb = sdb;
         mDevice = device;
     }
 
@@ -215,16 +222,15 @@ public final class SyncService implements Closeable {
      * @throws sdbCommandRejectedException if sdb rejects the command
      * @throws IOException If the connection to sdb failed.
      */
-    boolean openSync() throws TimeoutException, SdbCommandRejectedException, IOException {
+    public boolean openSync() throws TimeoutException, SdbCommandRejectedException, IOException {
         try {
-            mChannel = SocketChannel.open(mAddress);
-            mChannel.configureBlocking(false);
+               mChannel = sdb.openChannel();
 
             // target a specific device
             SdbHelper.setDevice(mChannel, mDevice);
 
             byte[] request = SdbHelper.formSdbRequest("sync:"); // $NON-NLS-1$
-            SdbHelper.write(mChannel, request, -1, SdbPreferences.getTimeOut());
+            SdbHelper.write(mChannel, request, -1, Preferences.getTimeOut());
 
             SdbResponse resp = SdbHelper.readSdbResponse(mChannel, false /* readDiagString */);
 
@@ -890,7 +896,7 @@ public final class SyncService implements Closeable {
      */
     private SyncResult doPullFile(String remotePath, String localPath,
             ISyncProgressMonitor monitor) {
-        return doPullFile(remotePath, localPath, monitor, null, SdbPreferences.getTimeOut());
+        return doPullFile(remotePath, localPath, monitor, null, Preferences.getTimeOut());
     }
 
     /**
@@ -1123,7 +1129,7 @@ public final class SyncService implements Closeable {
      */
     private SyncResult doPushFile(String localPath, String remotePath,
             ISyncProgressMonitor monitor) {
-        return doPushFile( localPath, remotePath, monitor, null, SdbPreferences.getTimeOut());
+        return doPushFile( localPath, remotePath, monitor, null, Preferences.getTimeOut());
     }
 
     /**
@@ -1352,7 +1358,7 @@ public final class SyncService implements Closeable {
     private void sync_quit() {
         byte[] msg = createReq(ID_QUIT, 0);
         try {
-            SdbHelper.write(mChannel, msg, -1, SdbPreferences.getTimeOut());
+            SdbHelper.write(mChannel, msg, -1, Preferences.getTimeOut());
         }catch (IOException e) {
             Log.e("sdb", "send quit error");
         }
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/ArrayUtil.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/ArrayUtil.java
new file mode 100644 (file)
index 0000000..c3de4e6
--- /dev/null
@@ -0,0 +1,930 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.util;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * ArrayUtil.
+ * 
+ * Helper related to array
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class ArrayUtil
+{
+       /**
+        * Empty {@link Object} array
+        */
+       public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+       
+
+       /**
+        * <p>
+        * check <code>collection</code> has no element.
+        * 
+        * use without null check.
+        * 
+        * Old style
+        * 
+        * <pre>
+        * Object[] array = null;
+        * ...
+        * if ( null != array && 0 < array.length ) {
+        *  ...
+        * }
+        * </pre>
+        * 
+        * Usage :
+        * <p>
+        * 
+        * <pre>
+        * Object[] array = null;
+        * ...
+        * if ( !ArrayUtil.isEmpty( array ) ) {
+        *      ...
+        * }
+        * </pre>
+        * 
+        * or "import static" style if you use JDK6
+        * 
+        * </pre>
+        * import static org.tizen.common.util.CollectionUtil.isEmpty;
+        * ...
+        *  
+        * Object[] array = null;
+        * ...
+        * if ( !isEmpty( array ) ) {
+        *      ...
+        * }
+        * </pre>
+        * 
+        * @param array {@link Collection} to check
+        * 
+        * @return value if collection is empty
+        */
+       public static <T>
+       boolean
+       isEmpty(
+               final T[] array
+       )
+       {
+               if ( null == array )
+               {
+                       return true;
+               }
+               
+               return (0 == array.length);
+       }
+       
+       /**
+        * <p>
+        * Return first element in <code>array</code><br>
+        * 
+        * Return <code>null</code> if <code>array</code> is null or empty
+        * </p>
+        * 
+        * @param <T> type of element in <code>array</code>
+        * @param array object array to check
+        * 
+        * @return first elemtn in <code>array</code>
+        */
+       public static <T>
+       T
+       pickupFirst( T[] array )
+       {
+               if ( isEmpty( array ) )
+               {
+                       return null;
+               }
+               
+               return array[0];
+       }
+
+       /**
+        * <p>
+        * Return last element in <code>array</code><br>
+        * 
+        * Return <code>null</code> if <code>array</code> is null or empty
+        * </p>
+        * 
+        * @param <T> type of element in <code>array</code>
+        * @param array object array to check
+        * 
+        * @return last elemtn in <code>array</code>
+        */
+       public static <T>
+       T
+       pickupLast( T[] array )
+       {
+               if ( isEmpty( array ) )
+               {
+                       return null;
+               }
+               
+               return array[array.length - 1];
+       }
+       
+       /**
+        * Create array with <code>length</code>
+        * 
+        * @param <T> type of element in array to create
+        * @param type {@link Class}
+        * @param length array size
+        * 
+        * @return created array
+        */
+       @SuppressWarnings("unchecked")
+       public static <T>
+       T[] newArray( Class<? extends T> type, int length)
+       {
+               return (T[]) Array.newInstance( type, length);
+       }
+
+       /**
+        * {@link Iterator} for array
+        *
+        * @param <K> element type in array
+        */
+       public static class
+       ArrayIterator<K>
+       implements Iterator<K>
+       {
+               /**
+                * cloned array
+                */
+               protected final K[] objs;
+
+               /**
+                * original array
+                */
+               protected final K[] origin;
+
+               /**
+                * current element index
+                */
+               protected int index = 0;
+               
+               /**
+                * Constructor with array
+                * 
+                * @param objs array to iterate
+                */
+               public
+               ArrayIterator(
+                       final K[] objs
+               )
+               {
+                       this.origin = objs;
+                       
+                       this.objs = ( null == origin )?null:origin.clone();
+               }
+
+               /* (non-Javadoc)
+                * @see java.util.Iterator#hasNext()
+                */
+               @Override
+               public
+               boolean
+               hasNext()
+               {
+                       if ( null == this.objs )
+                       {
+                               return false;
+                       }
+                       return ( index < this.objs.length );
+               }
+
+               /* (non-Javadoc)
+                * @see java.util.Iterator#next()
+                */
+               @Override
+               public
+               K
+               next()
+               {
+                       if ( null == this.objs )
+                       {
+                               throw new NoSuchElementException();
+                       }
+                       if ( this.objs.length <= index  )
+                       {
+                               throw new NoSuchElementException();
+                       }
+                       
+                       if ( objs[index] != origin[index] ) {
+                               throw new ConcurrentModificationException();
+                       }
+                       return this.objs[index++];
+               }
+
+               /* (non-Javadoc)
+                * @see java.util.Iterator#remove()
+                */
+               @Override
+               public
+               void
+               remove()
+               {
+                       throw new UnsupportedOperationException();
+               }
+
+       }
+       
+       /**
+        * Create and return {@link Iterator} for <code>array</code>
+        * 
+        * @param <T> iteraing element's type
+        * @param array array to iterate
+        * 
+        * @return {@link Iterator} for <code>array</code>
+        */
+       public static <T> Iterator<T> iterator( final T[] array )
+       {
+               return new ArrayIterator<T>( array );
+       }
+       
+       
+       /**
+        * Convert <code>source</code> to {@link Object[]}
+        * 
+        * throw {@link IllegalArgumentException} if source is not array type
+        * 
+        * @param source object to convert 
+        * 
+        * @return object to converted
+        */
+       public static
+       Object[]
+       toObjectArray(
+               final Object source
+       )
+       {
+               if ( source instanceof Object[] )
+               {
+                       return ( Object[] )source; 
+               }
+
+               if ( null == source )
+               {
+                       return EMPTY_OBJECT_ARRAY; 
+               }
+               
+               if ( !source.getClass().isArray() )
+               {
+                       throw new IllegalArgumentException( "source must be an array");
+               }
+
+               final int length = Array.getLength( source );
+               if ( 0 == length )
+               {
+                       return EMPTY_OBJECT_ARRAY; 
+               }
+               
+               Class<?> wrapperType = null;
+               for ( int i = 0 ; null == wrapperType && i < length ; ++i )
+               {
+                       Object obj = Array.get( source, 0 );
+                       if ( null == obj )
+                       {
+                               continue;
+                       }
+                       wrapperType = obj.getClass();
+               }
+               if ( null == wrapperType )
+               {
+                       return (Object[]) source;
+               }
+               
+               final Object[] newArray =
+                       (Object[]) Array.newInstance( wrapperType, length );
+               for( int i=0 ; i<length ; ++i )
+               {
+                       newArray[i] = Array.get( source, i );
+               }
+               
+               return newArray;
+       }
+       
+       /**
+        * Return size if object is array or {@link Collection}
+        * 
+        * Return <code>0</code> in case of the other type
+        * 
+        * @param obj object to check
+        * 
+        * @return size
+        */
+       public static
+       int
+       size(
+               final Object obj
+       )
+       {
+               if ( obj instanceof Object[] )
+               {
+                       return size( ( Object[] ) obj );
+               }
+               else if ( obj instanceof boolean[] )
+               {
+                       return size( ( boolean[] ) obj );
+               }
+               else if ( obj instanceof byte[] )
+               {
+                       return size( ( byte[] )obj );
+               }
+               else if ( obj instanceof char[] )
+               {
+                       return size( ( char[] ) obj );
+               }
+               else if ( obj instanceof short[] )
+               {
+                       return size( ( short[] )obj );
+               }
+               else if ( obj instanceof int[] )
+               {
+                       return size( (int[] ) obj );
+               }
+               else if ( obj instanceof long[] )
+               {
+                       return size( ( long[] ) obj );
+               }
+               else if ( obj instanceof float[] )
+               {
+                       return size( (float[] ) obj );
+               }
+               else if ( obj instanceof double[] )
+               {
+                       return size( ( double[] ) obj );
+               }
+               else if ( obj instanceof Collection )
+               {
+                       return CollectionUtil.size( (Collection<?>) obj );
+               }
+               return 0;
+       
+       }
+
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param objs boolean array object
+        * 
+        * @return size of array
+        */
+       public static
+       int
+       size(
+               final boolean[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+       
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param objs byte array object
+        * 
+        * @return size of array
+        */
+       public static
+       int
+       size(
+               final byte[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+       
+       
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param objs char array object
+        * 
+        * @return size of array
+        */
+       public static
+       int
+       size(
+               final char[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+       
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param objs short array object
+        * 
+        * @return size of array
+        */
+       public static
+       int
+       size(
+               final short[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+       
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param objs int array object
+        * 
+        * @return size of array
+        */
+       public static
+       int
+       size(
+               final int[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+       
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param objs long array object
+        * 
+        * @return size of array
+        */
+       public static
+       int
+       size(
+               final long[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+       
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param objs float array object
+        * 
+        * @return size of array
+        */
+       public static
+       int
+       size(
+               final float[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+       
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param objs double array object
+        * 
+        * @return size of array
+        */
+       public static
+       int
+       size(
+               final double[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+       
+       /**
+        * Return <code>objs</code>'s length
+        * 
+        * Return 0 if <code>objs</code> is null.
+        * 
+        * @param <T> type of array
+        * @param objs T type array object
+        * 
+        * @return size of array
+        */
+       public static <T>
+       int
+       size(
+               final T[] objs
+       ) {
+               if ( null == objs )
+               {
+                       return 0;
+               }
+               return objs.length;
+       }
+
+       /**
+        * add <code>obj</code> to <code>array</code>
+        * 
+        * Return array having only <code>obj</code> if <code>array</code> is <code>null</code>
+        * 
+        * @param array array to add element
+        * @param obj new element to add
+        * 
+        * @return added array
+        */
+       @SuppressWarnings("unchecked")
+       public static <T> T[]
+       add(
+               final T[] array,
+               final T obj
+       )
+       {
+               Class<?> compType = Object.class;
+               if ( null != array )
+               {
+                       compType = array.getClass().getComponentType();
+               }
+               else if ( null != obj )
+               {
+                       compType = obj.getClass();
+               }
+
+               final int newArrLength = size( array ) + 1;
+               final T[] newArr = 
+                       (T[]) Array.newInstance( compType, newArrLength );
+               
+               if ( null != array )
+               {
+                       System.arraycopy( array, 0, newArr, 0, array.length );
+               }
+               newArr[newArrLength - 1] = obj;
+               return newArr;
+       }
+       
+       /**
+        * remove elements whose index is between <code>startIndex</code> and <code>endIndex</code>
+        * 
+        * and return applied array
+        * 
+        * @param <T> type of array element
+        * @param array array to remove elements
+        * @param startIndex start index of range to remove
+        * @param endIndex end index of range to remove
+        * 
+        * @return change applied new array
+        * 
+        * @throws ArrayIndexOutOfBoundsException 
+        *              if <code>startIndex</code> or <code>endIndex</code> is not in range of array
+        * @throws IllegalArgumentException
+        *              if <code>startIndex</code> is greater than <code>endIndex</code>
+        */
+       @SuppressWarnings("unchecked")
+       public static <T> T[]
+       remove(
+               final Object[] array,
+               final int start,
+               final int end
+       )
+       {
+           Assert.notNull( array );
+               Assert.isTrue(
+                       start <= end,
+                       "start indnex(" + start + ") is greater than end index(" + end + ")"
+               );
+               
+               int startIndex = Math.max( 0, start );
+               int endIndex = Math.min( array.length, end );
+               if ( endIndex <= startIndex )
+               {
+                       return (T[]) array;
+               }
+               
+               final Class<?> compType = array.getClass().getComponentType();
+               
+               final int removeSize = endIndex - startIndex;
+
+               final int newArrLength = size( array ) - removeSize;
+               
+               final Object[] newArr = 
+                       (Object[]) Array.newInstance( compType, newArrLength );
+               
+               System.arraycopy( array, 0, newArr, 0, startIndex );
+               System.arraycopy( array, endIndex, newArr, startIndex, array.length-endIndex );
+               
+               return (T[]) newArr;
+       }
+
+       /**
+        * remove elements whose index is <code>index</code>
+        * 
+        * and return applied array
+        *
+        * @param <T> type of array element
+        * @param array array to remove elements
+        * @param index index to remove
+        * 
+        * @return change applied new array
+        * 
+        * @throws ArrayIndexOutOfBoundsException 
+        *              if <code>index</code> is not in range of array
+        */
+       public static <T> T[]
+       remove(
+               final Object[] array,
+               final int index
+       )
+       {
+               return remove( array, index, index + 1);
+       }
+
+       /**
+        * Check if <code>array</code> contains <code>element</code>
+        * 
+        * @param array array to check
+        * @param element object to check
+        * 
+        * @return <code>true</code> if <code>collection</code> contain <code>element</code>
+        */
+       public static <K, V>
+       boolean
+       contains(
+               final K[] array,
+               final V element
+       )
+       {
+               if ( null == array )
+               {
+                       return false;
+               }
+               
+               for ( final Object candidate : array )
+               {
+                       if ( ObjectUtil.equals( candidate, element ) )
+                       {
+                               return true; 
+                       }
+               }
+               return false;
+       }
+       
+       /**
+        * Return <code>index</code> th element in <code>collection</code>
+        * 
+        * Return <code>null</code> if <code>index</code> is out of range
+        * 
+        * @param <K> array type
+        * @param array array object to access
+        * @param index array index
+        * @return <code>index</code> th element in array
+        */
+       public static <K>
+       K
+       get(
+               final K[] array,
+               final int index
+       )
+       {
+               if ( null == array )
+               {
+                       return null;
+               }
+               if ( index < 0 )
+               {
+                       return null;
+               }
+               if ( array.length <= index )
+               {
+                       return null;
+               }
+               
+               return array[index];
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Boolean[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Boolean[] convertToWrapper( final boolean[] array )
+       {
+               final int nArray = size( array );
+               final Boolean[] ret = new Boolean[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Byte[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Byte[] convertToWrapper( final byte[] array )
+       {
+               final int nArray = size( array );
+               final Byte[] ret = new Byte[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+       
+       /**
+        * Convert <code>array</code> to {@link Character[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Character[] convertToWrapper( final char[] array )
+       {
+               final int nArray = size( array );
+               final Character[] ret = new Character[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+       
+       
+       /**
+        * Convert <code>array</code> to {@link Short[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Short[] convertToWrapper( final short[] array )
+       {
+               final int nArray = size( array );
+               final Short[] ret = new Short[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+       
+       /**
+        * Convert <code>array</code> to {@link Integer[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Integer[] convertToWrapper( final int[] array )
+       {
+               final int nArray = size( array );
+               final Integer[] ret = new Integer[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Long[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Long[] convertToWrapper( final long[] array )
+       {
+               final int nArray = size( array );
+               final Long[] ret = new Long[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Float[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Float[] convertToWrapper( final float[] array )
+       {
+               final int nArray = size( array );
+               final Float[] ret = new Float[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Double[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Double[] convertToWrapper( final double[] array )
+       {
+               final int nArray = size( array );
+               final Double[] ret = new Double[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       @SuppressWarnings("unchecked")
+    public static <T> T[] safe( T[] unsafe )
+       {
+           return (T[]) ObjectUtil.nvl( unsafe, EMPTY_OBJECT_ARRAY );
+       }
+}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/Assert.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/Assert.java
new file mode 100644 (file)
index 0000000..3d6c422
--- /dev/null
@@ -0,0 +1,838 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.util;
+
+import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Assert
+ * 
+ * Helper for assertion
+ * 
+ * Assert following
+ * <ul>
+ * <li>boolean expression</li>
+ * <li>null object</li>
+ * <li>object equality</li>
+ * <li>string</li>
+ * <li>Collection</li>
+ * <li>Map</li>
+ * <li>object type</li>
+ * </ul>
+ */
+public class 
+Assert
+{
+       protected Assert() { }
+
+       /**
+        * Encapsulated method in case of failure in assertion
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message.
+        * 
+        * @param msg exception's message to throw
+        */
+       public static
+       void
+       fail(
+               final Object msg
+       )
+       {
+               if ( msg instanceof String )
+               {
+                       throw new IllegalArgumentException( (String) msg );
+               } else if ( null != msg )
+               {
+                       throw new IllegalArgumentException( msg.toString() );
+               }
+       }
+
+       /**
+        * Assert that <code>exp</code> is <code>true</code>
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message 
+        * 
+        * if <code>exp</code> is <code>false</code>
+        * 
+        * @param exp boolean value to check
+        * @param msg exception's message to throw
+        * 
+        * @see #fail(Object)
+        */
+       public static
+       void
+       isTrue(
+               final boolean exp,
+               final String msg
+       )
+       {
+               if ( exp )
+               {
+                       return ;
+               }
+               fail( msg );
+       }
+       
+       /**
+        * Assert that <code>exp</code> is <code>false</code>
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message 
+        * 
+        * if <code>exp</code> is <code>true</code>
+        * 
+        * @param exp boolean value to check
+        * @param msg exception's message to throw
+        * 
+        * @see #fail(Object)
+        */
+       public static
+       void
+       isFalse(
+               final boolean exp,
+               final String msg
+       )
+       {
+               if ( !exp )
+               {
+                       return ;
+               }
+               fail( msg );
+       }
+       
+       /**
+        * Assert that <code>exp</code> is <code>true</code>
+        * 
+        * Throw {@link IllegalArgumentException} with "Expression must be true" message 
+        * 
+        * if <code>exp</code> is <code>false</code>
+        * 
+        * @param exp boolean value to check
+        * 
+        * @see #isTrue(boolean, String)
+        */
+       public static void 
+       isTrue(
+               final boolean exp
+       )
+       {
+               isTrue( exp, "Expression must be true" );
+       }
+       
+       /**
+        * Assert that <code>exp</code> is <code>false</code>
+        * 
+        * Throw {@link IllegalArgumentException} with "Expression must be false" message 
+        * 
+        * if <code>exp</code> is <code>true</code>
+        * 
+        * @param exp boolean value to check
+        * 
+        * @see #isFalse(boolean, String)
+        */
+       public static 
+       void 
+       isFalse(
+               final boolean exp
+       )
+       {
+               isFalse( exp, "Expression must be false" );
+       }
+       
+       /**
+        * Assert that <code>obj</code> is <code>null</code>
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message 
+        * 
+        * if <code>obj</code> is not <code>null</code>
+        * 
+        * @param obj object to check
+        * @param msg exception's message to throw
+        * 
+        * @see #isTrue(boolean, String)
+        */
+       public static
+       void
+       isNull(
+               final Object obj,
+               final String msg
+       )
+       {
+               isTrue( null == obj, msg );
+       }
+
+       /**
+        * Assert that <code>obj</code> is <code>null</code>
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message 
+        * 
+        * if <code>obj</code> is <code>null</code>
+        * 
+        * @param obj object to check
+        * @param msg exception's message to throw
+        * 
+        * @see #isFalse(boolean, String)
+        */
+       public static
+       void
+       notNull(
+               final Object obj,
+               final String msg
+       )
+       {
+               isFalse( null == obj, msg );
+       }
+       
+       /**
+        * Assert that <code>obj</code> is <code>null</code>
+        * 
+        * Throw {@link IllegalArgumentException} with "Object must be null" message 
+        * 
+        * if <code>obj</code> is not <code>null</code>
+        * 
+        * @param obj object to check
+        * 
+        * @see #isNull(Object, String)
+        */
+       public static
+       void
+       isNull(
+               final Object obj
+       )
+       {
+               isNull( obj, "Object must be null" );
+       }
+       
+       /**
+        * Assert that <code>obj</code> is not <code>null</code>
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message 
+        * 
+        * if <code>obj</code> is <code>null</code>
+        * 
+        * @param obj object to check
+        * 
+        * @see #notNull(Object, Object)
+        */
+       public static 
+       void 
+       notNull(
+               final Object obj
+       )
+       {
+               notNull( obj, "Object must NOT be null" );
+       }
+       
+       
+       /**
+        * Assert that two objects( <code>obj1</code> and <code>obj2</code> ) is equal.
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message 
+        * 
+        * if two objects is not equal
+        * 
+        * @param obj1 first object to compare
+        * @param obj2 second object to compare
+        * @param msg exception's message to throw
+        * 
+        * @see #fail(Object)
+        */
+       public static
+       void
+       isEqual(
+               final Object obj1,
+               final Object obj2,
+               final String message
+       )
+       {
+               if ( ObjectUtil.equals( obj1, obj2 ) )
+               {
+                       return ;
+               }
+               
+               fail( message );
+       }
+       
+       
+       /**
+        * Assert that two objects( <code>obj1</code> and <code>obj2</code> ) is equal.
+        * 
+        * Throw {@link IllegalArgumentException} with "Objects are not equal" message 
+        * 
+        * if two objects is not equal
+        * 
+        * @param obj1 first object to compare
+        * @param obj2 second object to compare
+        * 
+        * @see #isEqual(Object, Object, String)
+        */
+       public static
+       void
+       isEqual(
+               final Object obj1,
+               final Object obj2
+       )
+       {
+               isEqual( obj1, obj2, "Objects are not equal" );
+       }
+       
+       /**
+        * Assert that <code>text</code> has any readible character
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if <code>text</code> is <code>null</code> or empty string.
+        *  
+        * @param text string to check
+        * @param msg exception's message to throw
+        * 
+        * @see #fail(Object)
+        */
+       public static
+       void
+       hasLength(
+               final String text,
+               final String msg
+       )
+       {
+               if( StringUtil.hasLength( text ) )
+               {
+                       return ; 
+               }
+               fail( msg ); 
+       }
+       /**
+        * Assert that <code>text</code> has any readible character
+        * 
+        * Throw {@link IllegalArgumentException} with "String argument must have length; it must not be null or empty" message
+        * 
+        * if <code>text</code> is <code>null</code> or empty string.
+        *  
+        * @param text string to check
+        * 
+        * @see #hasLength(String, String)
+        */
+       public static
+       void
+       hasLength(
+               final String text
+       )
+       {
+               hasLength( text, "String argument must have length; it must not be null or empty" );
+       }
+
+
+       /**
+        * Assert that <code>text</code> has any readible character
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if <code>text</code> is <code>null</code>, empty string or string containing only unvisible character
+        *  
+        * @param text string to check
+        * @param msg exception's message to throw
+        * 
+        * @see #fail(Object)
+        */
+       public static
+       void
+       hasText(
+               final String text,
+               final String message
+       )
+       {
+               if ( StringUtil.hasText( text ) )
+               {
+                       return ; 
+               }
+               fail( message ); 
+       }
+
+       /**
+        * Assert that <code>text</code> has any readible character
+        * 
+        * Throw {@link IllegalArgumentException} with "String argument must have text; it must not be null, empty, or blank" message
+        * 
+        * if <code>text</code> is <code>null</code>, empty string or string containing only unvisible character
+        *  
+        * @param text string to check
+        * 
+        * @see #hasText(String, String)
+        */
+       public static
+       void
+       hasText(
+               final String text
+       )
+       {
+               hasText( text, "String argument must have text; it must not be null, empty, or blank" );
+       }
+
+       /**
+        * Assert that <code>textToSearch</code> does not have <code>substring</code> in part.
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if assertion is failure.
+        * 
+        * Assertion is successful if <code>textToSearch</code> or <code>substring</code> is <code>null</code>.
+        * 
+        * @param textToSearch search target string
+        * @param substring keyword to search
+        * @param msg exception's message to throw
+        * 
+        * @see String#contains(CharSequence)
+        */
+       public static
+       void
+       doesNotContain(
+               final String textToSearch,
+               final String substring,
+               final String msg
+       )
+       {
+               if ( !StringUtil.hasLength( textToSearch ) )
+               { 
+                       return ;
+               }
+               
+               if ( !StringUtil.hasLength( substring ) )
+               {
+                       return ;
+               }
+               
+               if ( !textToSearch.contains( substring ) )
+               {
+                       return ;
+               }
+               fail( msg );
+       }
+
+       /**
+        * Assert that <code>textToSearch</code> does not have <code>substring</code> in part.
+        * 
+        * Throw {@link IllegalArgumentException} with "String argument must not contain the substring [<code>substring</code>]" message
+        * 
+        * if assertion is failure.
+        * 
+        * Assertion is successful if <code>textToSearch</code> or <code>substring</code> is <code>null</code>.
+        * 
+        * @param textToSearch search target string
+        * @param substring keyword to search
+        * 
+        * @see #doesNotContain(String, String, String)
+        */
+       public static
+       void
+       doesNotContain(
+               final String textToSearch,
+               final String substring
+       )
+       {
+               doesNotContain(
+                       textToSearch,
+                       substring,
+                       "String argument must not contain the substring [" + substring + "]"
+               );
+       }
+       
+       /**
+        * Assert that <code>textToSearch</code> has <code>substring</code> in part.
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if assertion is failure.
+        * 
+        * Assertion is successful if <code>textToSearch</code> or <code>substring</code> is <code>null</code>.
+        * 
+        * @param textToSearch search target string
+        * @param substring keyword to search
+        * @param msg exception's message to throw
+        * 
+        * @see String#contains(CharSequence)
+        */
+       public static
+       void
+       contains(
+               final String textToSearch,
+               final String substring,
+               final String msg
+       )
+       {
+               if ( !StringUtil.hasLength( textToSearch ) )
+               {
+                       return ;
+               }
+               if ( !StringUtil.hasLength( substring ) ) 
+               {
+                       return ;
+               }
+               if ( textToSearch.contains( substring ) ) 
+               {
+                       return ;
+               }
+               fail( msg );
+       }
+
+       /**
+        * Assert that <code>textToSearch</code> does not have <code>substring</code> in part.
+        * 
+        * Throw {@link IllegalArgumentException} with "String argument must contain the substring [<code>substring</code>]" message
+        * 
+        * if assertion is failure.
+        * 
+        * Assertion is successful if <code>textToSearch</code> or <code>substring</code> is <code>null</code>.
+        * 
+        * @param textToSearch search target string
+        * @param substring keyword to search
+        * 
+        * @see #doesContain(String, String, String)
+        */
+       public static
+       void
+       contains(
+               final String textToSearch,
+               final String substring
+       )
+       {
+               contains(
+                       textToSearch,
+                       substring,
+                       "String argument must contain the substring [" + substring + "]"
+               );
+       }
+
+       /**
+        * Assert that <code>array</code> has a element at least.
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if <code>array</code> is null or empty array.
+        * 
+        * @param <T> type of array elemtent
+        * @param array array object to check
+        * @param msg exception's message to throw
+        * 
+        * @see ArrayUtil#isEmpty( Object[] )
+        */
+       public static <T>
+       void
+       notEmpty(
+               final T[] array,
+               final String message
+       )
+       {
+               if( ArrayUtil.isEmpty( array ) )
+               {
+                       fail( message );
+               }
+       }
+
+       /**
+        * Assert that <code>array</code> has a element at least.
+        * 
+        * Throw {@link IllegalArgumentException} with "Array must not be empty: it must contain at least 1 element" message
+        * 
+        * if <code>array</code> is null or empty array.
+        * 
+        * @param <T> type of array elemtent
+        * @param array array object to check
+        * @param msg exception's message to throw
+        * 
+        * @see #notEmpty( Object[] )
+        */
+       public static
+       void
+       notEmpty(
+               final Object[] array
+       )
+       {
+               notEmpty( array, "Array must not be empty: it must contain at least 1 element" );
+       }
+
+       /**
+        * Assert that there is no <code>null</code> in array elements
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if <code>array</code> has null element.
+        * 
+        * @param array array to check
+        * @param msg exception's message to throw
+        * 
+        * @see #fail(Object)
+        */
+       public static
+       void
+       noNullElements(
+               final Object[] array,
+               final String msg
+       )
+       {
+               
+               for ( int i=0, n=ArrayUtil.size( array ) ; i<n ; ++i )
+               {
+                       if ( null != array[i] )
+                       {
+                           continue;
+                       }
+                       
+                       fail( msg ); 
+               }
+       }
+
+       /**
+        * Assert that there is no <code>null</code> in array elements
+        * 
+        * Throw {@link IllegalArgumentException} with "Array must not contain any null elements" message
+        * 
+        * if <code>array</code> has null element.
+        * 
+        * @param array array to check
+        * 
+        * @see #noNullElements(Object[], String)
+        */
+       public static
+       void
+       noNullElements(
+               final Object[] array
+       ) {
+               noNullElements( array, "Array must not contain any null elements" );
+       }
+
+       
+       /**
+        * Assert that <code>collection</code>is not empty
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if <code>collection</code> has no element
+        * 
+        * @param collection {@link Collection} to check
+        * @param msg exception's message to throw
+        * 
+        * @see CollectionUtil#isEmpty( Collection )
+        * @see #fail(Object)
+        */
+       public static
+       void
+       notEmpty(
+               final Collection<?> collection,
+               final String msg
+       )
+       {
+               if( !CollectionUtil.isEmpty( collection ) )
+               {
+                       return ; 
+               }
+               fail( msg ); 
+       }
+
+       /**
+        * Assert that <code>collection</code>is not empty
+        * 
+        * Throw {@link IllegalArgumentException} with "Collection must not be empty: it must contain at least 1 element" message
+        * 
+        * if <code>collection</code> has no element
+        * 
+        * @param collection {@link Collection} to check
+        * 
+        * @see #notEmpty(Collection, String)
+        */
+       public static
+       void
+       notEmpty(
+               final Collection<?> collection
+       )
+       {
+               notEmpty( collection, "Collection must not be empty: it must contain at least 1 element" );
+       }
+       
+       /**
+        * Assert that <code>map</code>is not empty
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if <code>map</code> has no element
+        * 
+        * @param map {@link Map} to check
+        * @param msg exception's message to throw
+        * 
+        * @see MapUtil#isEmpty( Map )
+        * @see #fail(Object)
+        */
+       public static
+       void
+       notEmpty(
+               final Map<?, ?> map,
+               final String msg
+       )
+       {
+               if ( !MapUtil.isEmpty( map ) )
+               {
+                       return ; 
+               }
+               fail( msg ); 
+       }
+
+       /**
+        * Assert that <code>map</code>is not empty
+        * 
+        * Throw {@link IllegalArgumentException} with "Map must not be empty; it must contain at least one entry" message
+        * 
+        * if <code>map</code> has no element
+        * 
+        * @param map {@link Map} to check
+        * 
+        * @see #notEmpty(Map, String)
+        */
+       public static
+       void
+       notEmpty(
+               final Map<?, ?> map
+       )
+       {
+               notEmpty( map, "Map must not be empty; it must contain at least one entry" );
+       }
+
+       /**
+        * Assert that <code>obj</code> is instance of <code>type</code>
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if <code>obj</code> is <code>null</code> or not instance of <code>type</code>
+        * 
+        * @param type {@link Class} to check
+        * @param obj instance object to check
+        * @param msg exception's message to throw
+        * 
+        * @see Class#isInstance(Object)
+        * @see #fail(Object)
+        */
+       public static
+       void
+       isInstanceOf(
+               final Class<?> type,
+               final Object obj,
+               final String msg
+       )
+       {
+               notNull( type, "Type to check against must not be null" );
+               if( type.isInstance( obj ) )
+               {
+                       return ; 
+               }
+               
+               fail( MessageFormat.format(
+                       "{0}, Object of class [{1}] must be aan instance of {2}",
+                       msg,
+                       (( null == obj ) ?"null":obj.getClass().getName()),
+                       type
+               ) );
+       }
+
+       /**
+        * Assert that <code>obj</code> is instance of <code>type</code>
+        * 
+        * Throw {@link IllegalArgumentException}
+        * 
+        * if <code>obj</code> is <code>null</code> or not instance of <code>type</code>
+        * 
+        * @param type {@link Class} to check
+        * @param obj instance object to check
+        * 
+        * @see #isInstanceOf(Class, Object, String)
+        */
+       public static
+       void
+       isInstanceOf(
+               final Class<?> type,
+               final Object obj
+       )
+       {
+               isInstanceOf( type, obj, "" );
+       }
+
+       /**
+        * Assert that <code>superType</code> is assignable type from <code>subType</code> instance
+        * 
+        * Throw {@link IllegalArgumentException} with <code>msg</code> message
+        * 
+        * if <code>superType</code> or <code>subType</code> is <code>null</code> or if assertion is failure
+        * 
+        * @param superType super type candidate
+        * @param subType subtype candidate
+        * @param msg exception's message to throw
+        * 
+        * @see Class#isAssignableFrom(Class)
+        * @see #fail(Object)
+        */
+       public static
+       void
+       isAssignable(
+               final Class<?> superType,
+               final Class<?> subType,
+               final String msg
+       )
+       {
+               notNull( superType, "Type to check against must not be null" );
+               notNull( subType, "Type to assign must not be null" );
+               if( superType.isAssignableFrom( subType ) )
+               {
+                       return ;
+               }
+               fail( MessageFormat.format(
+                       "{0}, {1} is not assignable to {2}",
+                       msg,
+                       subType,
+                       superType
+               ) );
+       }
+
+       /**
+        * Assert that <code>superType</code> is assignable type from <code>subType</code> instance
+        * 
+        * Throw {@link IllegalArgumentException}
+        * 
+        * if <code>superType</code> or <code>subType</code> is <code>null</code> or if assertion is failure
+        * 
+        * @param superType super type candidate
+        * @param subType subtype candidate
+        * 
+        * @see #isAssignable(Class, Class, String)
+        */
+       public static
+       void
+       isAssignable(
+               final Class<?> superType,
+               final Class<?> subType
+       )
+       {
+               isAssignable( superType, subType, "" );
+       }
+
+}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/CollectionUtil.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/CollectionUtil.java
new file mode 100644 (file)
index 0000000..d8e015c
--- /dev/null
@@ -0,0 +1,1399 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.util;
+
+import static org.tizen.sdblib.util.StringUtil.EMPTY_STRING;
+import static org.tizen.sdblib.util.StringUtil.NULL_STRING;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.tizen.sdblib.util.ArrayUtil.ArrayIterator;
+
+/**
+ * CollectionUtil.
+ * 
+ * Helper related to collection( Set, List, etc )
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class CollectionUtil
+{
+    
+    /**
+     * Empty bytes
+     */
+    protected static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+    protected static final byte[] EMPTY_BYTES = EMPTY_BYTE_ARRAY;
+    
+    private static final String ARRAY_START = "{";
+    
+    private static final String ARRAY_END = "}";
+    
+    private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END;
+    
+    private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
+
+    private static final Set<Class<?>> APPROXIMABLE_COLLECTION_TYPES = 
+        Collections.unmodifiableSet( new HashSet<Class<?>>( Arrays.asList( new Class<?>[] {
+            Collection.class,
+            Set.class, HashSet.class, SortedSet.class, LinkedHashSet.class, TreeSet.class,
+            List.class, LinkedList.class, ArrayList.class
+        } ) ) );
+
+    private static final Set<Class<?>> APPROXIMABLE_MAP_TYPES = 
+        Collections.unmodifiableSet( new HashSet<Class<?>>( Arrays.asList( new Class<?>[] {
+            Map.class, SortedMap.class, HashMap.class, LinkedHashMap.class, TreeMap.class
+        } ) ) );
+    
+
+
+    /* Object */
+    /**
+     * Empty Collection
+     */
+    public static final Collection<Object> EMPTY_COLLECTION = 
+        Collections.unmodifiableCollection( new ArrayList<Object>() );
+
+    /**
+     * protected constructor
+     */
+    protected CollectionUtil() {}
+
+    /**
+     * <p>
+     * check <code>collection</code> has no element.
+     * 
+     * use without null check.
+     * 
+     * Old style
+     * 
+     * <code>
+     * List list = null;
+     * ...
+     * if ( null != list && !list.isEmpty() ) {
+     *  ...
+     * }
+     * </code>
+     * 
+     * Usage :
+     * <p>
+     * 
+     * <code>
+     * List list = null;
+     * ...
+     * if ( !CollectionUtil.isEmpty( list ) ) {
+     *  ...
+     * }
+     * </code>
+     * 
+     * or "import static" style if you use JDK6
+     * 
+     * </code>
+     * import static org.tizen.common.util.CollectionUtil.isEmpty;
+     *  
+     * ...
+     * List list = null;
+     * ...
+     * if ( !isEmpty( list ) ) {
+     *  ...
+     * }
+     * </code>
+     * 
+     * @param collection {@link Collection} to check
+     * 
+     * @return value if collection is empty
+     */
+    public static
+    boolean
+    isEmpty(
+        final Collection<?> collection
+    )
+    {
+        if ( null == collection )
+        {
+            return true;
+        }
+        
+        return collection.isEmpty();
+    }
+    
+    /**
+     * <p>
+     * Return <code>collection</code>'s size.
+     * 
+     * use without null check.
+     * 
+     * Return <code>0</code> if <code>collection</code> is <code>null</code>
+     * 
+     * <p>
+     * 
+     * Old style
+     * <code>
+     * if ( null != list ) {
+     *  for ( int i = 0, n = list.size() ; i < n ; ++i ) {
+     *      ...
+     *  }
+     * }
+     * </code>
+     * 
+     * 
+     * <code>
+     * for ( int i = 0, n = CollectionUtil.size( list ) ; i < n ; ++i ) {
+     *  ...
+     * }
+     *  
+     * </code>
+     * or "import static" style if you use JDK6
+     * 
+     * </code>
+     * import static org.tizen.common.util.CollectionUtil.isEmpty;
+     * ...
+     *  
+     * for ( int i = 0, n = size( list ) ; i < n ; ++i ) {
+     *  ...
+     * }
+     *  
+     * </code>
+     * 
+     * @param collection {@link Collection} to check
+     * 
+     * @return size of <code>collection</code>
+     * 
+     * @see Collection#size()
+     */
+    public static
+    int
+    size(
+        final Collection<?> collection
+    )
+    {
+        if ( null == collection )
+        {
+            return 0;
+        }
+        
+        return collection.size();
+    }
+
+    /**
+     * <p>
+     * Return first element in <code>collection</code><br>
+     * 
+     * Return <code>null</code> if <code>collection</code> is null or empty
+     * </p>
+     * @param <T> type of element in <code>collection</code>
+     * @param collection {@link Collection} to check
+     * 
+     * @return first elemtn in <code>collection</code>
+     */
+    public static <T>
+    T
+    pickupFirst( final Collection<T> collection )
+    {
+        if ( isEmpty( collection ) )
+        {
+            return null;
+        }
+        
+        final Iterator<T> iter = collection.iterator();
+        return (iter.hasNext())?(iter.next()):null;
+    }
+
+    /**
+     * <p>
+     * Extract and return first element in <code>collection</code><br>
+     * 
+     * Return <code>null</code> if <code>collection</code> is null or empty
+     * </p>
+     * @param <T> type of element in <code>collection</code>
+     * @param collection {@link Collection} to check
+     * 
+     * @return first elemtn in <code>collection</code>
+     */
+    public static <T>
+    T
+    removeFirst( final Collection<T> collection )
+    {
+        if ( isEmpty( collection ) )
+        {
+            return null;
+        }
+        
+        final Iterator<T> iter = collection.iterator();
+        if ( iter.hasNext() )
+        {
+            T ret = iter.next();
+            iter.remove();
+            return ret;
+        }
+        return null;
+    }
+
+
+    /**
+     * <p>
+     * Return last element in <code>collection</code><br>
+     * 
+     * Return <code>null</code> if <code>collection</code> is null or empty
+     * 
+     * Don't use this in case of big data or looping algorithm
+     * </p>
+     * @param <T> type of element in <code>collection</code>
+     * @param collection {@link Collection} to check
+     * 
+     * @return last elemtn in <code>collection</code>
+     */
+    public static <T>
+    T
+    pickupLast( final Collection<T> collection )
+    {
+        if ( isEmpty( collection ) )
+        {
+            return null;
+        }
+        
+        final Iterator<T> iter = collection.iterator();
+        
+        T temp = null;
+        while ( iter.hasNext() )
+        {
+            temp = iter.next();
+        }
+        return temp;
+    }
+    
+    /**
+     * <p>
+     * Extract and return last element in <code>collection</code><br>
+     * 
+     * Return <code>null</code> if <code>collection</code> is null or empty
+     * 
+     * Don't use this in case of big data or looping algorithm
+     * </p>
+     * @param <T> type of element in <code>collection</code>
+     * @param collection {@link Collection} to check
+     * 
+     * @return last elemtn in <code>collection</code>
+     */
+    public static <T>
+    T
+    removeLast( final Collection<T> collection )
+    {
+        if ( isEmpty( collection ) )
+        {
+            return null;
+        }
+        
+        final Iterator<T> iter = collection.iterator();
+        
+        T temp = null;
+        while ( iter.hasNext() )
+        {
+            temp = iter.next();
+        }
+        iter.remove();
+        return temp;
+    }
+
+    /**
+     * Convert {@link Enumeration} to {@link Iterator} using decoration pattern 
+     * 
+     * @param <K> element type to be handled by enumertaion
+     */
+    static class
+    EnumerationAdapter<K>
+    implements Iterator<K>
+    {
+        protected final Enumeration<K> enumeration;
+        /**
+         * Constructor with {@link Enumeration}
+         * 
+         * @param enumeration {@link Enumeration} to convert 
+         */
+        public
+        EnumerationAdapter(
+            final Enumeration<K> enumeration
+        )
+        {
+            Assert.notNull( enumeration );
+            this.enumeration = enumeration;
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#hasNext()
+         */
+        @Override
+        public
+        boolean
+        hasNext()
+        {
+            return enumeration.hasMoreElements();
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#next()
+         */
+        @Override
+        public
+        K
+        next()
+        {
+            return enumeration.nextElement();
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#remove()
+         */
+        @Override
+        public
+        void
+        remove()
+        {
+            throw new UnsupportedOperationException();
+        }
+    }
+    
+    /**
+     * 
+     * Return Iterator to be converted from <code>enumeration</code>
+     * 
+     * @param <E> element type interating <code>enumeration</code>
+     * @param enumeration {@link Enumeration} object to be converted
+     * 
+     * @return converted {@link Iterator}
+     */
+    public
+    static <E>
+    Iterator<E>
+    iterator(
+        final Enumeration<E> enumeration
+    ) {
+        return new EnumerationAdapter<E>( enumeration );
+    }
+
+    
+    /**
+     * Convert array object to {@link List}
+     * 
+     * @param source array candidate object
+     * 
+     * @return converted {@link List}
+     */
+    public static
+    List<?>
+    asList(
+        final Object source
+    )
+    {
+        return Arrays.asList( ArrayUtil.toObjectArray( source ) );
+    }
+
+    /**
+     * 
+     * Add array object to <code>collection</code>
+     * 
+     * @param array array candidate object to be added
+     * @param collection {@link Collection} to add
+     * 
+     * @see ArrayUtil#toObjectArray(Object)
+     */
+    public static
+    void
+    mergeArrayIntoCollection(
+        final Object array,
+        final Collection<Object> collection
+    )
+    {
+        Assert.notNull( collection );
+        final Object[] arr = ArrayUtil.toObjectArray( array );
+        for ( int i=0, n=arr.length ; i<n ; ++i )
+        {
+            collection.add( arr[i] );
+        }
+    }
+
+    /**
+     * Check if <code>iterator</code> meet <code>element</code> in iteration
+     * 
+     * @param iterator iterating object
+     * @param element object to check
+     * 
+     * @return <code>true</code> if <code>iterator</code> meet <code>element</code>
+     */
+    public static
+    boolean
+    contains(
+        final Iterator<Object> iterator,
+        final Object element
+    )
+    {
+        if ( null == iterator )
+        {
+            return false;
+        }
+        
+        while ( iterator.hasNext() )
+        {
+            final Object candidate = iterator.next();
+            if ( ObjectUtil.equals( candidate, element ) ) 
+            {
+                return true; 
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check if <code>enumeration</code> meet <code>element</code> in iteration
+     * 
+     * @param enumeration iterating object
+     * @param element object to check
+     * 
+     * @return <code>true</code> if <code>enumeration</code> meet <code>element</code>
+     */
+    public static
+    boolean
+    contains(
+        final Enumeration<Object> enumeration,
+        final Object element
+    )
+    {
+        if ( null == enumeration )
+        {
+            return false;
+        }
+        while( enumeration.hasMoreElements() )
+        {
+            final Object candidate = enumeration.nextElement();
+            if ( ObjectUtil.equals( candidate, element ) )
+            {
+                return true; 
+            }
+        }
+        return false;
+    }
+
+
+    
+    /**
+     * Check if <code>collection</code> contains <code>element</code>
+     * 
+     * @param collection {@link Collection} to check
+     * @param element object to check
+     * 
+     * @return <code>true</code> if <code>collection</code> contain <code>element</code>
+     */
+    public static
+    boolean
+    contains(
+        final Collection<Object> collection,
+        final Object element
+    )
+    {
+        if ( null == collection )
+        {
+            return false;
+        }
+        for ( final Object candidate : collection )
+        {
+            if ( ObjectUtil.equals( candidate, element ) )
+            {
+                return true; 
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Check and return if <code>source</code> contain any element of <code>candidates</code>
+     * 
+     * @param source {@link Collection} to check
+     * @param candidates {@link Collection} whose element is expected in <code>source</code>
+     * 
+     * @return <code>true</code> if <code>source</code> contain any elemnt of <code>candidates</code>
+     */
+    public static
+    boolean
+    containsAny(
+        final Collection<?> source,
+        final Collection<?> candidates
+    )
+    {
+        if ( isEmpty( source ) || isEmpty( candidates) )
+        {
+            return false; 
+        }
+
+        for ( final Object candidate : candidates )
+        {
+            if ( source.contains( candidate ) )
+            {
+                return true; 
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check <code>collectionType</code> is approximable collection type
+     * 
+     * @param collectionType type to check
+     * 
+     * @return <code>true</code> if <code>collectionType</code> is in {@link #APPROXIMABLE_COLLECTION_TYPES} 
+     * 
+     * @see #APPROXIMABLE_COLLECTION_TYPES
+     */
+    public static
+    boolean
+    isApproximableCollectionType(
+        final Class<?> collectionType
+    )
+    {
+        return APPROXIMABLE_COLLECTION_TYPES.contains( collectionType );
+    }
+    
+    /**
+     * Check <code>mapType</code> is approximable map type
+     * 
+     * @param mapType type to check
+     * 
+     * @return <code>true</code> if <code>mapType</code> is in {@link #APPROXIMABLE_MAP_TYPES} 
+     * 
+     * @see #APPROXIMABLE_MAP_TYPES
+     */
+    public static
+    boolean
+    isApproximableMapType(
+        final Class<?> mapType
+    )
+    {
+        return APPROXIMABLE_MAP_TYPES.contains( mapType );
+    }
+    
+    /**
+     * Create <code>collection</code> matched approximable collection
+     * 
+     * @param <K> containing type
+     * @param collection {@link Collection} to convert
+     * @param initialCapacity initial size of created collection
+     * 
+     * @return created approximable collection
+     */
+    public static <K>
+    Collection<K>
+    createApproximableCollection(
+        final Collection<K> collection,
+        final int initialCapacity
+    )
+    {
+        if ( collection instanceof LinkedList<?> )
+        {
+            return new LinkedList<K>();
+        }
+        else if ( collection instanceof List<?> )
+        {
+            return new ArrayList<K>( initialCapacity);
+        }
+        else if ( collection instanceof SortedSet<?> )
+        {
+            return new TreeSet<K>( ( (SortedSet<K>)collection).comparator() );
+        }
+        else
+        {
+            return new LinkedHashSet<K>( initialCapacity);
+        }
+    }
+    
+    /**
+     * @param <K> Map's Key type
+     * @param <V> Map's Value type
+     * @param map Map argument
+     * @param initialCapacity initial argument for Map which will be created
+     * 
+     * @return created ApproximableMap
+     */
+    public static <K, V>
+    Map<K, V>
+    createApproximableMap(
+        final Map<K, V> map,
+        final int initialCapacity
+    )
+    {
+        if ( map instanceof SortedMap<?, ?> )
+        {
+            return new TreeMap<K, V>( ( (SortedMap<K, V>) map).comparator() );
+        }
+        else
+        {
+            return new LinkedHashMap<K, V>( initialCapacity );
+        }
+    }
+    
+    /* print */
+    
+    /**
+     * Converts <code>obj</code> object to String.
+     * 
+     * @param obj object to convert
+     * 
+     * @return converted String
+     */
+    public static
+    String
+    toString(
+        final Object obj
+    )
+    {
+        if ( null == obj )
+        {
+            return NULL_STRING;
+        }
+
+        if ( obj instanceof String )
+        {
+            return (String) obj;
+        }
+        else if ( obj.getClass().isArray() )
+        {
+            int length = Array.getLength( obj );
+            
+            if ( 0 == length )
+            {
+                return EMPTY_ARRAY; 
+            }
+            
+            final StringBuilder buffer= new StringBuilder();
+            
+            buffer.append( ARRAY_START);
+            for ( int i=0 ; i<length ; ++i )
+            {
+                if ( 0 != i ) {
+                    buffer.append( ARRAY_ELEMENT_SEPARATOR );
+                }
+                
+                buffer.append( toString( Array.get( obj, i ) ) );
+            }
+            buffer.append( ARRAY_END );
+            return buffer.toString();
+        }
+        return ObjectUtil.nvl( obj.toString(), EMPTY_STRING );
+    }
+
+    /**
+     * Returns a String from <code>array</code> Object[] with String separator.
+     * 
+     * @param array Object[] to combine
+     * @param separator the delimiter which is used when Object[] combined
+     * 
+     * @return combined String
+     */
+    public static <E>
+    String
+    concatenate(
+        final E[] array,
+        final String separator
+    )
+    {
+        return concatenate( (null==array)?null:new ArrayIterator<E>( array ), separator ); 
+    }
+        
+    /**
+     * Returns a String from col {@link Collection} with String separator.  
+     * 
+     * @param col {@link Collection} object to combine
+     * @param separator the delimiter which is used when {@link Collection} object combined
+     * 
+     * @return combined String
+     */
+    public static <E>
+    String
+    concatenate(
+        final Collection<E> col,
+        final String separator
+    )
+    {
+        return concatenate( (null==col)?(null):col.iterator(), separator ); 
+    }
+    
+    /**
+     * Returns a String from {@link Iterator} with String separator.
+     * 
+     * @param iter {@link Iterator} to combine objects
+     * @param separator the delimiter which is used when {@link Iterator} combined
+     * 
+     * @return combined String
+     */
+    public static <E>
+    String
+    concatenate(
+        Iterator<E> iter,
+        final String separator
+    )
+    {
+        if ( null == iter )
+        {
+            return NULL_STRING;
+        }
+        
+        if ( !iter.hasNext() )
+        {
+            return EMPTY_ARRAY; 
+        }
+        
+        final StringBuilder buffer= new StringBuilder();
+        boolean bInit = false;
+        
+        while ( iter.hasNext() )
+        {
+            Object obj = iter.next();
+            if ( bInit )
+            {
+                buffer.append( separator );
+            }
+            bInit = true;
+            
+            buffer.append( toString( obj ) );
+        }
+        return buffer.toString();
+    }
+    
+    /* Hash */
+    private static final int MULTIPLIER= 31;
+
+    private static final int INITIAL_HASH = 7;
+    
+    /**
+     * Creates hash value about object.
+     * <br>
+     * In case of array, get hash value using object's hash value in the array.
+     * 
+     * @param obj object to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final Object obj
+    )
+    {
+        if ( null == obj )
+        {
+            return 0;
+        }
+        if ( obj.getClass().isArray() )
+        {
+            if ( obj instanceof Object[] )
+            {
+                return hashCode( (Object[] )obj );
+            }
+            else if ( obj instanceof boolean[] )
+            {
+                return hashCode( (boolean[] )obj );
+            }
+            else if ( obj instanceof byte[] )
+            {
+                return hashCode( (byte[] )obj);
+            }
+            else if ( obj instanceof char[] )
+            {
+                return hashCode( (char[] )obj);
+            }
+            else if ( obj instanceof double[] )
+            {
+                return hashCode( (double[] )obj);
+            }
+            else if ( obj instanceof float[] )
+            {
+                return hashCode( (float[] )obj);
+            }
+            else if ( obj instanceof int[] )
+            {
+                return hashCode( (int[] )obj);
+            }
+            else if ( obj instanceof long[] )
+            {
+                return hashCode( (long[] )obj);
+            }
+            else if ( obj instanceof short[] )
+            {
+                return hashCode( (short[] )obj);
+            }
+        }
+        
+        return obj.hashCode();
+    }
+
+    /**
+     * Returns hash value about <code>array</code> Object[].
+     * 
+     * @param array Object[] to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final Object[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + hashCode( array[i] );
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>array</code> boolean[].
+     * 
+     * @param array boolean[] to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final boolean[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + hashCode( array[i] );
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>array</code> int[].  
+     * 
+     * @param array int[] to get hash value
+     * 
+     * @return hash value
+     */
+    public static int
+    hashCode(
+        final byte[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + array[i];
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>array</code> char[].
+     * 
+     * @param array char[] to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final char[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + hashCode( array[i] );
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>array</code> double[].
+     * 
+     * @param array double[] to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int 
+    hashCode(
+        final double[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + hashCode( array[i] );
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>array</code> float[].
+     * 
+     * @param array float[] to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final float[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + hashCode( array[i] );
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>array</code> int[].
+     * 
+     * @param array int[] to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final int[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + hashCode( array[i] );
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>array</code> long[].
+     * 
+     * @param array long[] to get hash value 
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final long[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + hashCode( array[i] );
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>array</code> short[].
+     * 
+     * @param array short[] to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final short[] array
+    )
+    {
+        if ( null == array )
+        {
+            return 0;
+        }
+        
+        int hash = INITIAL_HASH;
+        for( int i=0, arraySize=array.length ; i<arraySize ; ++i )
+        {
+            hash = MULTIPLIER * hash + hashCode( array[i] );
+        }
+
+        return hash;
+    }
+
+    /**
+     * Returns hash value about <code>bool</code> boolean.
+     * 
+     * @param bool boolean type parameter to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final boolean bool
+    )
+    {
+        return bool ? 1231 : 1237;
+    }
+
+    /**
+     * Return hash value about <code>dbl</code> double.
+     * 
+     * @param dbl double type parameter to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final double dbl
+    )
+    {
+        long bits = Double.doubleToLongBits( dbl );
+        return hashCode( bits );
+    }
+
+    /**
+     * Returns hash value about <code>flt</code> float.
+     * 
+     * @param flt float type parameter to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        float flt
+    )
+    {
+        return Float.floatToIntBits( flt );
+    }
+
+
+    /**
+     * Returns hash value about <code>lng</code> long.
+     * 
+     * @param lng long type parameter to get hash value
+     * 
+     * @return hash value
+     */
+    public static
+    int
+    hashCode(
+        final long lng
+    )
+    {
+        return (int) ( lng ^ ( lng >>> 32 ) );
+    }
+    
+    /* Equals */
+    /**
+     * Returns whether it is same object type or not by comparing each column's type of {@link Collection} object.
+     * 
+     * @param <K> object type about {@link Collection}
+     * @param cols {@link Collection} objects
+     * 
+     * @return true if each column's type of the {@link Collection} object is same
+     */
+    @SuppressWarnings("unchecked")
+    public static <K>
+    boolean
+    equals(
+        final Collection<? extends K>... cols
+    )
+    {
+        
+        // flag if collection is null
+        boolean bInit = false;
+        int size = 0;
+        for ( final Collection<? extends K> col : cols )
+        {
+            if ( !bInit )
+            {
+                if ( null == col )
+                {
+                    size = -1;
+                }
+                else
+                {
+                    size = col.size();
+                }
+                bInit = true;
+            }
+            if ( size < 0 )
+            {
+                if ( null != col )
+                {
+                    return false;
+                }
+            }
+            else if ( null == col || col.size() != size )
+            {
+                return false;
+            }
+        }
+        if ( size < 0 )
+        {
+            return true;
+        }
+
+        final Iterator<? extends K>[] iters = new Iterator[cols.length];
+        for ( int i = 0, n = iters.length ; i<n ; ++i )
+        {
+            iters[i] = cols[i].iterator();
+        }
+        
+        while ( iters[0].hasNext() )
+        {
+            final K obj = iters[0].next();
+            for ( int i = 1, n = iters.length ; i<n ; ++i )
+            {
+                final K other = iters[i].next();
+                
+                if ( !ObjectUtil.equals( obj, other ) )
+                {
+                    return false;
+                }
+            }
+        }
+        
+        return true;
+    }
+    
+    /**
+     * Returns whether it is same object type or not by comparing each column's type of Object[].
+     * 
+     * @param objsVar target objects
+     * 
+     * @return true if each column's type of the Object[] is same
+     * 
+     */
+    public static
+    boolean
+    equals(
+        final Object[]... objsVar
+    )
+    {
+        // flag if collection is null
+        boolean bInit = false;
+        int size = 0;
+        for ( final Object[] objs : objsVar )
+        {
+            if ( !bInit )
+            {
+                if ( null == objs )
+                {
+                    size = -1;
+                }
+                else
+                {
+                    size = objs.length;
+                }
+                bInit = true;
+            }
+            if ( size < 0 )
+            {
+                if ( null != objs )
+                {
+                    return false;
+                }
+            }
+            else if ( null == objs || objs.length != size )
+            {
+                return false;
+            }
+        }
+        if ( size < 0 )
+        {
+            return true;
+        }
+
+        
+        for ( int i=1, n=objsVar.length ; i<n ; ++i )
+        {
+            for ( int j=0 ; j<size ; ++j )
+            {
+                if ( !ObjectUtil.equals( objsVar[0][j], objsVar[i][j] ) )
+                {
+                    return false;
+                }
+            }
+        }
+        return true;
+
+    }
+    
+    /**
+     * <p>
+     * Swaps <code><I>i</I></code>th object's location with <code><I>j</I></code>th object in <code>objs</code> Object[].
+     * </p>
+     * @param objs target
+     * @param i location of object to be swapped
+     * @param j location of object to be swapped
+     */
+    public static
+    void
+    swap(
+        final Object[] objs,
+        final int i,
+        final int j
+    )
+    {
+        Object temp = objs[i];
+        objs[i] = objs[j];
+        objs[j] = temp;
+    }
+    
+    /**
+     * 
+     * Check that target class is available class to be inserted in the collection.
+     * If return is positive, target class is available.
+     * If return is negative, target class is not available.
+     * If return is zero, we cannot judge that target class is available or not.
+     * For example, if collection size is zero, or every element in the collection is null, we cannot judge it.
+     * Although collection is defined for Object, all of its elements are String, it returns negative,
+     * because we cannot know generic type exactly in runtime.  
+     * 
+     * @param collection
+     * @param targetClass
+     * @return
+     * @author ho.namkoong{@literal <ho.namkoong@samsung.com>}
+     */
+    public static 
+    int 
+    isAvailableGenericTypeForCollection(
+        final Collection<?> collection,
+        final Class<?> targetClass
+    ) 
+    {
+        if(collection.size() < 1) {
+            return 0;
+        }
+        boolean foundNotNull = false;
+        for(Object o: collection) {
+            if(o != null) {
+                foundNotNull = true;
+                if(o.getClass().isAssignableFrom(targetClass)) {
+                    return 1;
+                }
+            }
+        }
+        if(foundNotNull) {
+            return -1;
+        }
+        return 0;
+    }
+    
+    /**
+     * 
+     * Resolve set as list.
+     * Result list has same order of iterator of set. 
+     * 
+     * @param set set to be resolved as a list.
+     * @return list which contains all the elements in the set.
+     * @author ho.namkoong{@literal <ho.namkoong@samsung.com>}
+     */
+    public static <E>
+    List<E> 
+    resolveSetAsList(
+        final Set<E> set
+    ) 
+    {
+        Iterator<E> itr = set.iterator();
+        ArrayList<E> result = new ArrayList<E>();
+        
+        while(itr.hasNext()) {
+             E obj = itr.next();
+             result.add(obj);
+        }
+        
+        return result;
+    }
+}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/IOUtil.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/IOUtil.java
new file mode 100644 (file)
index 0000000..f91eb4e
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib.util;\r
+\r
+import java.io.Closeable;\r
+import java.io.IOException;\r
+import java.nio.channels.Selector;\r
+\r
+\r
+/**\r
+ * IOUtil\r
+ * \r
+ * Utility for I/O\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+public class\r
+IOUtil\r
+{\r
+\r
+       public static void tryClose( Closeable obj )\r
+       {\r
+               if ( null == obj )\r
+               {\r
+                       return ;\r
+               }\r
+               try\r
+        {\r
+               obj.close();\r
+        }\r
+               catch ( final IOException e )\r
+        {\r
+               Log.e( "sdb", "failed to close :" + e );\r
+        }\r
+       }\r
+       \r
+       public static void tryClose( final Selector selector )\r
+       {\r
+               if ( null == selector )\r
+               {\r
+                       return ;\r
+               }\r
+               \r
+               try\r
+        {\r
+               selector.close();\r
+        }\r
+               catch ( final IOException e )\r
+        {\r
+               Log.e( "sdb", "close failed :" + e );\r
+\r
+        }\r
+       }\r
+}\r
@@ -1,20 +1,29 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ *  sdblib
  *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
  * 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
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
  */
-
-package org.tizen.sdblib;
+package org.tizen.sdblib.util;
 
 import java.io.File;
 import java.io.FileWriter;
@@ -24,97 +33,20 @@ import java.io.StringWriter;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
+import org.tizen.sdblib.SmartDevelopmentBridge;
+
 /**
  * Log class that mirrors the API in main SLP sources.
  * <p/>Default behavior outputs the log to {@link System#out}. Use
  * {@link #setLogOutput(com.samsung.sdblib.Log.ILogOutput)} to redirect the log somewhere else.
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
  */
-public final class Log {
+public class
+Log
+{
 
     private static File logFile = null;
-    /**
-     * Log Level enum.
-     */
-    public enum LogLevel {
-        VERBOSE(2, "Verbose", 'V'), //$NON-NLS-1$
-        DEBUG(3, "Debug", 'D'), //$NON-NLS-1$
-        INFO(4, "Info", 'I'), //$NON-NLS-1$
-        WARN(5, "Warning", 'W'), //$NON-NLS-1$
-        ERROR(6, "Error", 'E'), //$NON-NLS-1$
-        FATAL(7, "Fatal", 'F'); //$NON-NLS-1$
-
-        private int mPriorityLevel;
-        private String mStringValue;
-        private char mPriorityLetter;
-
-        LogLevel(int intPriority, String stringValue, char priorityChar) {
-            mPriorityLevel = intPriority;
-            mStringValue = stringValue;
-            mPriorityLetter = priorityChar;
-        }
-
-        public static LogLevel getByString(String value) {
-            for (LogLevel mode : values()) {
-                if (mode.mStringValue.equals(value)) {
-                    return mode;
-                }
-            }
-
-            return null;
-        }
-        
-        /**
-         * Returns the {@link LogLevel} enum matching the specified letter.
-         * @param letter the letter matching a <code>LogLevel</code> enum
-         * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
-         */
-        public static LogLevel getByLetter(char letter) {
-            for (LogLevel mode : values()) {
-                if (mode.mPriorityLetter == letter) {
-                    return mode;
-                }
-            }
-
-            return null;
-        }
-
-        /**
-         * Returns the {@link LogLevel} enum matching the specified letter.
-         * <p/>
-         * The letter is passed as a {@link String} argument, but only the first character
-         * is used. 
-         * @param letter the letter matching a <code>LogLevel</code> enum
-         * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
-         */
-        public static LogLevel getByLetterString(String letter) {
-            if (letter.length() > 0) {
-                return getByLetter(letter.charAt(0));
-            }
-
-            return null;
-        }
-
-        /**
-         * Returns the letter identifying the priority of the {@link LogLevel}.
-         */
-        public char getPriorityLetter() {
-            return mPriorityLetter;
-        }
-
-        /**
-         * Returns the numerical value of the priority.
-         */
-        public int getPriority() {
-            return mPriorityLevel;
-        }
-
-        /**
-         * Returns a non translated string representing the LogLevel.
-         */
-        public String getStringValue() {
-            return mStringValue;
-        }
-    }
     
     /**
      * Classes which implement this interface provides methods that deal with outputting log
@@ -139,8 +71,6 @@ public final class Log {
         public void printAndPromptLog(LogLevel logLevel, String tag, String message);
     }
 
-    private static LogLevel mLevel = SdbPreferences.getLogLevel();
-
     private static ILogOutput sLogOutput;
 
     private static final char[] mSpaceLine = new char[72];
@@ -235,10 +165,6 @@ public final class Log {
         }
     }
 
-    static void setLevel(LogLevel logLevel) {
-        mLevel = logLevel;
-    }
-
     /**
      * Sets the {@link ILogOutput} to use to print the logs. If not set, {@link System#out}
      * will be used.
@@ -327,7 +253,7 @@ public final class Log {
 
     /* currently prints to stdout; could write to a log window */
     private static void println(LogLevel logLevel, String tag, String message) {
-        if (logLevel.getPriority() >= mLevel.getPriority()) {
+        if (logLevel.getPriority() >= Preferences.getLogLevel().getPriority()) {
             if (sLogOutput != null) {
                 sLogOutput.printLog(logLevel, tag, message);
             } else {
@@ -355,7 +281,7 @@ public final class Log {
     public static String getLogFormatString(LogLevel logLevel, String tag, String message) {
         SimpleDateFormat formatter = new SimpleDateFormat("hh:mm:ss");
         return String.format("%s %c/%s: %s\n", formatter.format(new Date()),
-                logLevel.getPriorityLetter(), tag, message);
+                logLevel.getLetter(), tag, message);
     }
     
     public static void printLog(String msg)
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/LogLevel.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/LogLevel.java
new file mode 100644 (file)
index 0000000..aa3a4f2
--- /dev/null
@@ -0,0 +1,158 @@
+/*\r
+ *  sdblib\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+package org.tizen.sdblib.util;\r
+\r
+\r
+/**\r
+ * LogLevel\r
+ * \r
+ * Log Level enum.\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ */\r
+public enum\r
+LogLevel\r
+{\r
+    /**\r
+     * Verbose level, priority 2\r
+     */\r
+    VERBOSE( 2, "Verbose"), //$NON-NLS-1$\r
+    /**\r
+     * Debug level, priority 3\r
+     */\r
+    DEBUG( 3, "Debug" ), //$NON-NLS-1$\r
+    /**\r
+     * Info level, priority 4\r
+     */\r
+    INFO( 4, "Info" ), //$NON-NLS-1$\r
+    /**\r
+     * Warn level, priority 5\r
+     */\r
+    WARN( 5, "Warning" ), //$NON-NLS-1$\r
+    /**\r
+     * Error level, priority 6\r
+     */\r
+    ERROR( 6, "Error" ), //$NON-NLS-1$\r
+    /**\r
+     * Fatal level, priority 7\r
+     */\r
+    FATAL( 7, "Fatal" ); //$NON-NLS-1$\r
+\r
+    private final int priority;\r
+    \r
+    /**\r
+     * level name\r
+     */\r
+    private final String name;\r
+    /**\r
+     * Letter to print out\r
+     */\r
+    private char letter;\r
+\r
+    /**\r
+     * Constructor with priority and name\r
+     * \r
+     * @param priority log level's priority\r
+     * @param name level name\r
+     */\r
+    LogLevel(\r
+       final int priority,\r
+       final String name\r
+    )\r
+    {\r
+        this.priority = priority;\r
+        this.name = name;\r
+        this.letter = name.charAt( 0 );\r
+    }\r
+\r
+    public static\r
+    LogLevel getByName(\r
+       final String name\r
+    )\r
+    {\r
+        for ( final LogLevel mode : values() )\r
+        {\r
+            if ( mode.name.equals( name ) )\r
+            {\r
+                return mode;\r
+            }\r
+        }\r
+\r
+        return null;\r
+    }\r
+    \r
+    /**\r
+     * Returns the {@link LogLevel} enum matching the specified letter.\r
+     * @param letter the letter matching a <code>LogLevel</code> enum\r
+     * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.\r
+     */\r
+    public static LogLevel getByLetter(char letter) {\r
+        for (LogLevel mode : values()) {\r
+            if (mode.letter == letter) {\r
+                return mode;\r
+            }\r
+        }\r
+\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Returns the {@link LogLevel} enum matching the specified letter.\r
+     * <p/>\r
+     * The letter is passed as a {@link String} argument, but only the first character\r
+     * is used. \r
+     * @param letter the letter matching a <code>LogLevel</code> enum\r
+     * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.\r
+     */\r
+    public static LogLevel getByLetterString(String letter) {\r
+        if (letter.length() > 0) {\r
+            return getByLetter(letter.charAt(0));\r
+        }\r
+\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Returns the letter identifying the priority of the {@link LogLevel}.\r
+     */\r
+    public char getLetter() {\r
+        return letter;\r
+    }\r
+\r
+    /**\r
+     * Returns the numerical value of the priority.\r
+     */\r
+    public int getPriority() {\r
+        return priority;\r
+    }\r
+\r
+    /**\r
+     * Returns a non translated string representing the LogLevel.\r
+     */\r
+    public String getName() {\r
+        return name;\r
+    }\r
+}\r
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/MapUtil.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/MapUtil.java
new file mode 100644 (file)
index 0000000..bcb53c1
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.util;
+
+import static org.tizen.sdblib.util.StringUtil.NULL_STRING;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * MapUtil.
+ * 
+ * Helper related to {@link Map}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class MapUtil
+{
+       /**
+        * protected constructor
+        */
+       protected MapUtil() {}
+       
+       /**
+        * Return <code>map</code>'s size
+        * 
+        * Return <code>0</code>, if <code>map</code> is <code>null</code>
+        * 
+        * @param map {@link Map} to count elements
+        * 
+        * @return the number of element in <code>map</code>
+        */
+       public static
+       int
+       length(
+               final Map<?, ?> map
+       )
+       {
+               if ( null == map )
+               {
+                       return 0;
+               }
+               return map.size();
+       }
+       
+
+       /**
+        * Check if <code>map</code> is empty
+        * 
+        * Return <code>true</code>, if <code>map</code> is <code>null</code> or has no element
+        * 
+        * @param map {@link Map} to check
+        * 
+        * @return if map is empty
+        */
+       public static
+       boolean
+       isEmpty(
+               final Map<?, ?> map
+       )
+       {
+               return ( 0 == length( map ) );
+       }
+       
+    /**
+     * Return {@link Map} for <code>keys</code> and <code>values</code>
+     * 
+     * add i th object of <code>values</code>  with i th object of <code>keys</code> as key
+     * 
+     * @param <K> key type
+     * @param <V> value type
+     * @param keys keys to add
+     * @param values values to add
+     * 
+     * @return {@link Map} containing <code>keys</code> - <code>values</code> pairs
+     */
+    public static <K, V>
+    Map<K, V>
+    asMap(
+       final K[] keys,
+       final V[] values
+    )
+    {
+       final HashMap<K, V> map = new HashMap<K, V>();
+       if ( null == keys || null == values )
+       {
+               return map;
+       }
+       
+       for ( int i=0, n=Math.min( keys.length, values.length ) ; i<n ; ++i )
+       {
+               map.put( keys[i], values[i] );
+       }
+       return map;
+    }
+    
+
+       /**
+        * Return {@link Map} for <code>objs</code>
+        * 
+        * <code>objs</code> is {@link Object[]} that each element is key-value pair.
+        * 
+        * @param <A> key type
+        * @param <B> value type
+        * @param objs key-value pairs to add
+        * 
+        * @return created {@link Map}
+        */
+       @SuppressWarnings("unchecked")
+       public static <A extends Object, B extends Object>
+       Map<A, B>
+       asMap(
+               final Object[][] objs
+       )
+       {
+       final HashMap<A, B> map = new HashMap<A, B>();
+       for ( int i=0, n=ArrayUtil.size( objs ) ; i<n ; ++i )
+       {
+               if ( 2 != objs[i].length )
+               {
+                       continue;
+               }
+               map.put( (A) objs[i][0], (B) objs[i][1] );
+       }
+       return map;
+    }
+       
+       /**
+        * Add {@link Properties}'s key-value pairs to <code>map</code>
+        * 
+        * @param props {@link Properties} to provide key-value pairs
+        * @param map {@link Map} to be added
+        */
+       public static
+       void
+       mergePropertiesIntoMap(
+               final Properties props,
+               final Map<Object, Object> map
+       )
+       {
+           Assert.notNull( map );
+               if ( null == props )
+               {
+                       return ;
+               }
+               
+               final Enumeration<?> en = props.propertyNames();
+               while (  en.hasMoreElements() )
+               {
+                       final String key = (String) en.nextElement();
+                       map.put( key, props.getProperty( key ) );
+               }
+       }
+       
+       /**
+        * Return string to present {@link Map} for human
+        * 
+        * @param map {@link Map} to print out
+        * 
+        * @return string of presentation
+        */
+       public static
+       String
+       toString(
+               final Map<?, ?> map
+       )
+       {
+               if ( null == map )
+               {
+                       return NULL_STRING;
+               }
+               
+               final StringBuilder buffer = new StringBuilder();
+               buffer.append( "{" );
+               
+               if ( !map.isEmpty() )
+               {
+                       buffer.append( "\n" );
+                       for ( final Object key : map.keySet() )
+                       {
+                               buffer.append( "\t" );
+                               buffer.append( key.toString() );
+                               buffer.append( "=" );
+                               buffer.append( map.get( key ) );
+                               buffer.append( "\n" );
+                       }
+               }
+               buffer.append( "}" );
+               return buffer.toString();
+       }
+
+}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/ObjectUtil.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/ObjectUtil.java
new file mode 100644 (file)
index 0000000..a665c6b
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.util;
+
+import static org.tizen.sdblib.util.StringUtil.NULL_STRING;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * ObjectUtil.
+ * 
+ * Helper related to <code>Object</code> or generic logic
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class ObjectUtil {
+       
+       /**
+        * protected constructor
+        */
+       protected ObjectUtil() {}
+       
+    /**
+     * Returns first non-null element in args
+     * <br>
+     * Returns null if no non-null element
+     * 
+     * @param <T> arguments' type
+     * @param args arguments to check
+     * 
+     * @return non-null element in <code>args</code>
+     */
+       public static <T> T nvl( T... args )
+       {
+               if ( null == args )
+               {
+                       return null;
+               }
+               
+               for ( final T arg : args )
+               {
+                       if ( null != arg )
+                       {
+                               return arg;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Hexadecimal IP
+        */
+       private static String hexServerIP = null;
+
+       /**
+        * Seed generator for GUID
+        */
+       private static final SecureRandom SEEDER = new SecureRandom();
+
+    /**
+     * Compares two objects.
+     * <br>
+     * {@link Object#equals(Object)} is used for equality but this needs null check.
+     * <br>
+     * two object are equal if both are <code>null</code>
+     * <br>
+     * <pre>
+     * if ( null == obj1 ) {
+     *  if ( obj1 == obj2 ) {
+     *      ...
+     *  }
+     * } else if ( obj1.equals( obj2 ) ) {
+     *      ...
+     * } 
+     * </pre>
+     * If you use this method 
+     * <pre>
+     * if ( ObjectUtils.equals( obj1, obj2 ) ) {
+     * ...
+     * }
+     * </pre>
+     * Recursively compre if object is {@link Collection} or array
+     * <br>
+     * 
+     * @param obj1 object1 to compare
+     * @param obj2 object2 to compare
+     * 
+     * @return <code>true</code> if two object are equal
+     */
+       public static
+       boolean
+       equals( 
+               final Object obj1,
+               final Object obj2
+       )
+       {
+               if ( obj1 == obj2 )
+               {
+                       return true;
+               }
+               if ( null == obj1 || null == obj2 )
+               {
+                       return false;
+               }
+
+               if ( !obj1.getClass().isArray() || !obj2.getClass().isArray() )
+               {
+                       return obj1.equals( obj2 );
+               }
+
+               // in case of array
+               if ( obj1 instanceof boolean[] && obj2 instanceof boolean[] )
+               {
+                       return Arrays.equals( ( boolean[] ) obj1, ( boolean[] ) obj2 );
+               }
+               else if ( obj1 instanceof byte[] && obj2 instanceof byte[] )
+               {
+                       return Arrays.equals( ( byte[] ) obj1, ( byte[] ) obj2 );
+               }
+               else if ( obj1 instanceof char[] && obj2 instanceof char[] )
+               {
+                       return Arrays.equals( ( char[] ) obj1, ( char[] ) obj2 );
+               }
+               else if ( obj1 instanceof double[] && obj2 instanceof double[] )
+               {
+                       return Arrays.equals( ( double[] ) obj1, ( double[] ) obj2 );
+               }
+               else if ( obj1 instanceof float[] && obj2 instanceof float[] )
+               {
+                       return Arrays.equals( ( float[] ) obj1, ( float[] ) obj2 );
+               }
+               else if ( obj1 instanceof int[] && obj2 instanceof int[] )
+               {
+                       return Arrays.equals( ( int[] ) obj1, ( int[] ) obj2 );
+               }
+               else if ( obj1 instanceof long[] && obj2 instanceof long[] )
+               {
+                       return Arrays.equals( ( long[] ) obj1, ( long[] ) obj2 );
+               }
+               else if ( obj1 instanceof short[] && obj2 instanceof short[] )
+               {
+                       return Arrays.equals( ( short[] ) obj1, ( short[] ) obj2 );
+               }
+               return false;
+       }
+
+       /**
+        * Convert byte[] to integer
+        * 
+        * @param bytes byte array to convert
+        * 
+        * @return converted integer
+        */
+       public static
+       int
+       getInt(
+               final byte bytes[]
+       )
+       {
+               int i= 0;
+               int j= 24;
+               for( int k=0 ; 0<=j ; ++k )
+               {
+                       int l = bytes[k] & 0xff;
+                       i += l << j;
+                       j -= 8;
+               }
+               return i;
+       }
+
+       /**
+        * Pad <code>str</code> to string with <code>length</code> length
+        * 
+        * Return <code>str</code> if string's length is greater than <code>length</code>
+        * 
+        * The padding character is '0'
+        * 
+        * @param str string to pad
+        * @param length length to pad
+        * 
+        * @return padded string
+        */
+       private static
+       String
+       padHex(
+               final String str,
+               final int length
+       )
+       {
+               final StringBuilder buffer = new StringBuilder();
+               for( int j=0, n=length-str.length() ; j<n ; ++j )
+               {
+                       buffer.append( '0' );
+               }
+               buffer.append( str.subSequence( str.length() - Math.min( str.length(), length ), str.length() ) );
+               return buffer.toString();
+       }
+
+       /**
+        * Convert <code>i</code> to hexadecimal with <code>j</code> length
+        * 
+        * @param i decimal to convert
+        * @param j hexadecimal's length
+        * 
+        * @return converted hexadecimal
+        */
+       public static
+       String
+       hexFormat(
+               final int i,
+               final int j
+       )
+       {
+               final String s = Integer.toHexString( i );
+               return padHex( s, j );
+       }
+
+
+       /**
+        * Create GUID with 32 bytes
+        * 
+        * GUID is used for system( programe ) not human
+        * 
+        * Structure
+        * +-----------------+--------------+----------------------+------------------+
+        * | Current Time(8) | Server IP(8) | Object Hash Value(8) | Random Number(8) |
+        * +-----------------+--------------+----------------------+------------------+
+        * 
+        * @param obj object to hash
+        * @return create guid
+        */
+       public static final
+       String
+       generateGUID(
+               final Object obj
+       )
+       {
+               final StringBuilder guid = new StringBuilder( 32 );
+
+               // time
+               long timeNow = System.currentTimeMillis();
+               int timeLow = (int) timeNow& 0xFFFFFFFF;
+               guid.append( hexFormat( timeLow, 8 ) );
+
+               // server IP
+               if ( null == hexServerIP )
+               {
+                       InetAddress localInetAddress = null;
+                       try
+                       {
+                               // get the inet address
+                               localInetAddress = InetAddress.getLocalHost();
+                       }
+                       catch( final UnknownHostException uhe )
+                       {
+                               try
+                               {
+                                       localInetAddress = InetAddress.getByName( "localhost" );
+                               }
+                               catch ( final UnknownHostException e )
+                               {
+                                       e.printStackTrace();
+                                       return null;
+                               }
+                       }
+
+                       byte serverIP[] = localInetAddress.getAddress();
+
+                       hexServerIP = hexFormat( getInt( serverIP ), 8 );
+               }
+               guid.append( hexServerIP );
+
+               // object hash
+               guid.append( hexFormat( System.identityHashCode( obj ), 8 ) );
+
+               // random number
+               int node= -1;
+               synchronized( SEEDER )
+               {
+                       node = SEEDER.nextInt();
+               }
+               guid.append( hexFormat( node, 8 ) );
+               return guid.toString();
+       }
+       
+       /* Serialize / Deserialize */
+       /**
+        * Serialize object
+        * 
+        * @param obj object to serialize
+        * 
+        * @return serialized byte array
+        * 
+        * @throws IOException If serialization is fail
+        * 
+        * @see ObjectOutputStream#writeObject( Object )
+        */
+       public static
+       byte[]
+       serialize(
+               final Object obj
+       )
+       throws IOException
+       {
+               final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+               final ObjectOutputStream objOut = new ObjectOutputStream( byteOut );
+               objOut.writeObject( obj );
+               return byteOut.toByteArray();
+       }
+
+       /**
+        * Deserialize byte array
+        * 
+        * @param bytes bytes to deserialize
+        * 
+        * @return Deserialized object
+        * 
+        * @throws IOException If deserialization is fail
+        * 
+        * @throws ClassNotFoundException If No class
+        * 
+        * @see ObjectInputStream#readObject()
+        */
+       public static
+       Object
+       deserialize(
+               final byte[] bytes
+       )
+       throws IOException, ClassNotFoundException
+       {
+               Assert.notNull( bytes, "bytes must not be null" );
+               final ByteArrayInputStream byteIn = new ByteArrayInputStream( bytes );
+               final ObjectInputStream objIn = new ObjectInputStream( byteIn );
+               return objIn.readObject();
+       }
+
+       /**
+        * Create and return object's simple name
+        * 
+        * Use 4 hash value instead of 8 hash value
+        * 
+        * @param obj object to convert
+        * 
+        * @return textual string for <code>obj</code>
+        */
+       public static
+       String
+       toString(
+               final Object obj
+       )
+       {
+               if ( null == obj )
+               {
+                       return NULL_STRING;
+               }
+               final StringBuilder builder = new StringBuilder();
+               builder.append( obj.getClass().getSimpleName() );
+               builder.append( '@' );
+               int hash = obj.hashCode();
+               
+               for ( int i = 8 ; i>=0 ; i-=8 )
+               {
+                       StringUtil.appendHexa( builder, 0xFF & ( hash >> i ) );
+               }
+               
+               
+               return builder.toString();
+       }
+}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/ParsingUtil.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/ParsingUtil.java
new file mode 100644 (file)
index 0000000..e971413
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+*  sdblib
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* BonYong Lee <bonyong.lee@samsung.com>
+* 
+* 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.
+*
+* Contributors:
+* - S-Core Co., Ltd
+*
+*/
+package org.tizen.sdblib.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+
+/**
+ * ParsingUtil.
+ * 
+ * Helper related to parsing of textual implication
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class ParsingUtil
+{
+       
+       /**
+        * semantic <code>true</code>
+        */
+       protected static final Collection<String> BOOLEAN_TRUE =
+               Collections.unmodifiableCollection( new HashSet<String>( Arrays.asList(
+                       "1", "yes", "y", "true", "t"
+               ) ) );
+       
+       /**
+        * sematic <code>false</code>
+        */
+       protected static final Collection<String> BOOLEAN_FALSE =
+               Collections.unmodifiableCollection( new HashSet<String>( Arrays.asList(
+                       "no, n", "false", "f", "0"
+               ) ) );
+       
+       /**
+        * parse text and convert to <code>boolean</code>
+        * 
+        * return <code>defaultValue</code> if can't parse or convert
+        * 
+        * @param value string to parse
+        * @param defaultValue default value when exception case
+        * 
+        * @return converted <code>boolean</code> value
+        */
+       public static
+       boolean
+       parseBoolean(
+               final String value,
+               final boolean defaultValue
+       )
+       {
+               if ( null == value )
+               {
+                       return defaultValue;
+               }
+               
+               final String safe = StringUtil.trim( value ).toLowerCase();
+               return ((defaultValue)?BOOLEAN_FALSE:BOOLEAN_TRUE).contains( safe ) ^ defaultValue;
+               
+       }
+       
+       /**
+        * parse text and convert to <code>int</code>
+        * 
+        * return <code>defaultValue</code> if can't parse or convert
+        * 
+        * @param value string to parse
+        * @param defaultValue default value when exception case
+        * 
+        * @return converted <code>int</code> value
+        */
+       public static
+       int parseInt(
+               final String value,
+               final int defaultValue
+       )
+       {
+               if ( null == value )
+               {
+                       return defaultValue;
+               }
+               
+               final String trimmed = StringUtil.trim( value );
+               return Integer.decode( trimmed );
+       }
+       
+       /**
+        * parse text and convert to <code>long</code>
+        * 
+        * return <code>defaultValue</code> if can't parse or convert
+        * 
+        * @param value string to parse
+        * @param defaultValue default value when exception case
+        * 
+        * @return converted <code>long</code> value
+        */
+       public static
+       long
+       parseLong(
+               final String value,
+               final long defaultValue
+       )
+       {
+               if ( null == value )
+               {
+                       return defaultValue;
+               }
+               
+               final String trimmed = StringUtil.trim( value );
+               try
+               {
+                       return Long.decode( trimmed );
+               }
+        catch ( final NumberFormatException e )
+               {
+                       return defaultValue;
+               }
+               
+       }
+       
+       /**
+        * parse text and convert to <code>double</code>
+        * 
+        * return <code>defaultValue</code> if can't parse or convert
+        * 
+        * @param value string to parse
+        * @param defaultValue default value when exception case
+        * 
+        * @return converted <code>double</code> value
+        */
+       public static
+       double
+       parseDouble(
+               final String value,
+               final double defaultValue
+       )
+       {
+               if ( null == value )
+               {
+                       return defaultValue;
+               }
+               
+               final String trimmed = StringUtil.trim( value );
+               try
+               {
+                       return Double.valueOf( trimmed );
+               }
+        catch ( final NumberFormatException e )
+               {
+                       return defaultValue;
+               }
+               
+       }
+
+}
@@ -1,22 +1,30 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ *  sdblib
  *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
  * 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
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
  */
+package org.tizen.sdblib.util;
 
-package org.tizen.sdblib;
-
-import org.tizen.sdblib.Log.LogLevel;
 
 /**
  * Preferences for the sdb library.
@@ -27,53 +35,81 @@ import org.tizen.sdblib.Log.LogLevel;
  * right away, while other methods will have no effect once {@link AndroidDebugBridge#init(boolean)}
  * has been called.
  * <p/>Check the documentation of each method.
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
  */
-public final class SdbPreferences {
+public class
+Preferences
+{
 
        public static LogLevel DEFAULT_LOG_LEVEL = LogLevel.ERROR;
-    /** Default timeout values for sdb connection (milliseconds) */
+       
+    /**
+     * Default timeout values for sdb connection (milliseconds)
+     */
     public static final int DEFAULT_TIMEOUT = 5000; // standard delay, in ms
 
-    private static LogLevel sLogLevel = DEFAULT_LOG_LEVEL;
-    private static int sTimeOut = DEFAULT_TIMEOUT;
+    /**
+     * Log level
+     */
+    private static LogLevel logLevel = DEFAULT_LOG_LEVEL;
+    /**
+     * Timeout
+     */
+    private static int timeout = DEFAULT_TIMEOUT;
     
-    private static final String DEFAULT_LOG_LEVEL_PROPERTY = System.getProperty("default.sdblib.loglevel");
+    /**
+     * Default log level from jvm properties
+     */
+    private static final String DEFAULT_LOG_LEVEL_PROPERTY = System.getProperty( "default.sdblib.loglevel" );
 
     /**
      * Returns the minimum {@link LogLevel} being displayed.
      */
-    public static LogLevel getLogLevel() {
-        String default_level = DEFAULT_LOG_LEVEL_PROPERTY;
-        if(default_level != null)
+    public static
+    LogLevel
+    getLogLevel()
+    {
+        String defaultLevel = DEFAULT_LOG_LEVEL_PROPERTY;
+        if ( null == defaultLevel )
         {
-            LogLevel levels[] = LogLevel.values();
-            for(LogLevel level : levels)
-            {
-                if(level.getPriority() == Integer.parseInt(default_level))
-                {
-                    DEFAULT_LOG_LEVEL = level;
-                    return DEFAULT_LOG_LEVEL;
-                }
-            }
+               return logLevel;
         }
-        return sLogLevel;
+        
+        final LogLevel levels[] = LogLevel.values();
+        for( final LogLevel level : levels )
+        {
+               if ( level.getPriority() == Integer.parseInt( defaultLevel ) )
+               {
+                       return DEFAULT_LOG_LEVEL = level;
+               }
+        }
+        return logLevel;
     }
 
     /**
      * Sets the minimum {@link LogLevel} to display.
      * <p/>This change takes effect right away.
      */
-    public static void setLogLevel(String value) {
-        sLogLevel = LogLevel.getByString(value);
-
-        Log.setLevel(sLogLevel);
+    public static
+    void
+    setLogLevel(
+       final String value
+    )
+    {
+       LogLevel l = LogLevel.getByName( value );
+       if ( null == l )
+       {
+               return ;
+       }
+        logLevel = l;
     }
 
     /**
      * Returns the timeout to be used in sdb connections (milliseconds).
      */
     public static int getTimeOut() {
-        return sTimeOut;
+        return timeout;
     }
 
     /**
@@ -82,13 +118,13 @@ public final class SdbPreferences {
      * @param timeOut the timeout value (milliseconds).
      */
     public static void setTimeOut(int timeOut) {
-        sTimeOut = timeOut;
+        timeout = timeOut;
     }
 
     /**
      * Non accessible constructor.
      */
-    private SdbPreferences() {
+    private Preferences() {
         // pass, only static methods in the class.
     }
 }
index 53f59c5..fb3e8d7 100755 (executable)
@@ -32,7 +32,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 
-import org.tizen.sdblib.Log;
 
 public class SdbShellProcess extends Process {
 
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/StreamGobbler.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/StreamGobbler.java
new file mode 100644 (file)
index 0000000..ef92a91
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.util;
+
+import static org.tizen.sdblib.util.IOUtil.tryClose;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+public class StreamGobbler extends Thread
+{
+       InputStream is;
+       OutputStream os;
+       String result;
+       private static Object synchronizer = new Object();
+       
+       
+       public StreamGobbler(InputStream is) {
+               this.is = is;
+               this.os = null;
+       }
+
+       public StreamGobbler(InputStream is, OutputStream os) {
+               this.is = is;
+               this.os = os;
+       }
+
+       public void run()
+       {
+               final StringBuffer buffer = new StringBuffer();
+               BufferedReader br = null;
+               try {           
+                       synchronized (synchronizer) {
+                               br = new BufferedReader(new InputStreamReader(is));
+                               String line;
+                               while ( null != (line = br.readLine() ) )
+                               {
+                                       buffer.append(line);
+                                       buffer.append("\n");
+                                       
+                                       if ( os != null )
+                                       {
+                                               os.write( (line + "\n").getBytes());
+                                       }
+                                       
+                    Log.e( "gobbler", line );
+                               }
+                       }
+               } catch (IOException ioe) {
+               Log.e( "sdb", "failed to read stream:" +  ioe );
+               } finally {
+                       result = buffer.toString();
+                       tryClose( br );
+               }
+       }
+       
+       public String getResult() {
+               return result;
+       }
+}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/StringUtil.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/StringUtil.java
new file mode 100644 (file)
index 0000000..9e1a0e4
--- /dev/null
@@ -0,0 +1,1093 @@
+/*
+ *  sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * @author Changhyun Lee {@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *  <ul>
+ *  <li> initial creation
+ *  <li> added trimToNull method.
+ *  </ul> 
+ *  @author gyeongseok.seo@samsung.com, S-Core Inc. 
+ *  <ul>
+ *  <li> added split method.
+ *  <li> added removeStart method.
+ *  </ul> 
+ */
+public class StringUtil
+{
+    /**
+     * Empty String
+     */
+    public static final String EMPTY_STRING = "";
+
+    /**
+     * Textual string for <code>null</code>
+     */
+    public static final String NULL_STRING = "<<null>>";
+
+    /**
+     * Textual string for empty byte array
+     */
+    public static final String EMPTY_BYTES_STRING = "<<EMPTY BYTES>>";
+
+    /**
+     * Line separator string
+     */
+    public static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
+
+    /**
+     * TAB string
+     */
+    public static final String TAB = "\t";
+
+    /* Dump Format */
+    protected static char CONTROL_CHARS_SHOWER = '.';
+
+    /**
+     * Hexa decimal conversion map
+     */
+    protected static final char[] HEXA_CHARS = new char[] {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+    /**
+     * The number how many bytes is in int
+     */
+    protected static final int N_INT_BY_BYTE = 4;
+
+    /**
+     * The number how many characters is print out in a line
+     */
+    protected static final int WIDTH_PER_LINE = 16;
+
+    /**
+     * Character to express for control( Human can't control character and control character break log format )
+     */
+    protected static char TWO_BYTES_CHARS_SHOWER = '?';
+
+    /**
+     * Return meaningful value of <code>str</code>
+     * 
+     * Return <code>null</code> if <code>str</code> has no implication
+     * 
+     * @param str string to check
+     * 
+     * @return meaningful string
+     * 
+     * @see #trimToNull(String, String)
+     */
+    public static
+    String
+    trimToNull(
+        final String str
+    )
+    {
+        return trimToNull(str, null);
+    }
+
+    /**
+     * Return meaningful value of <code>str</code>
+     * 
+     * Return <code>def</code> if <code>str</code> has no implication
+     * 
+     * @param str string to check
+     * 
+     * @return meaningful string
+     * 
+     * @see #getMeaningful(String)
+     * @see #isEmpty(CharSequence)
+     */
+    public static String trimToNull(String str, String def) {
+        final String meaningful = getMeaningful( str );
+        return isEmpty( meaningful )?def:meaningful;
+    }
+
+    /**
+     * Convert <code>src</code> to {@link InputStream}
+     * 
+     * @param src string to convert
+     * 
+     * @return {@link InputStream} containing <code>src</code>
+     */
+    public static
+    InputStream
+    toInputStream(
+        final String src
+    )
+    {
+        if ( null == src )
+        {
+            return null;
+        }
+        return new ByteArrayInputStream( src.getBytes() );
+    }
+
+    /**
+     * Split <code>str</code> with <code>delimiters</code>
+     * 
+     * @param str string to split
+     * @param delimiters delimiters to split with
+     * 
+     * @return strings to be split
+     */
+    public static
+    String[] split(
+        final String str,
+        final String delimiters
+    )
+    {
+        final List<String> list = new ArrayList<String>();
+        final StringTokenizer tokenizer = new StringTokenizer( str, delimiters );
+        while ( tokenizer.hasMoreTokens() )
+        {
+            list.add( tokenizer.nextToken() );
+        }
+
+        return (String[]) list.toArray(new String[0]);
+    }
+
+    public static String asString(Reader reader) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        int c;
+        while ((c = reader.read()) != -1) {
+            sb.append((char) c);
+        }
+        return sb.toString();
+    }
+    public static String asString(InputStream is) throws IOException{
+        StringBuffer out = new StringBuffer();
+        byte[] b = new byte[4096];
+
+        for (int n; (n = is.read(b)) != -1;)
+        {
+            out.append(new String(b,0,n));
+        }
+        return out.toString();
+    }
+
+    public static String removeEnd(String str, String remove) {
+        if (isEmpty(str) || isEmpty(remove)) {
+            return str;
+        }
+        if (str.endsWith(remove)) {
+            return str.substring(0, str.length() - remove.length());
+        }
+        return str;
+    }
+
+    /**
+     * remove string in target string
+     * if target is empty or remove word is empty then just return target string
+     * 
+     * @param str - target string
+     * @param remove - remove string
+     * @return removed target string
+     */
+    public static String removeStart(String str, String remove) {
+        if (isEmpty(str) || isEmpty(remove) ) {
+            return str;
+        }
+        if (str.startsWith(remove)){
+            return str.substring(remove.length());
+        }
+        return str;
+    }
+
+    /* Logging */
+    /**
+     * </p>
+     * Append hexa value for <code>ch</code> to <code>buffer</code>
+     *
+     * Hexa value must be two digit. Pad 0 if hexa value has 1 digit.
+     * </p>
+     *
+     * @param buffer {@link StringBuilder} to write
+     * @param ch decimal integer
+     */
+    public static
+    void
+    appendHexa(
+        final StringBuilder buffer,
+        final int ch
+    )
+    {
+        if ( ch < 16 )
+        {
+            // if 1 digit containing hexadecimal
+            buffer.append( '0' );
+            buffer.append( HEXA_CHARS[( 0x0f & ( ch ) )] );
+        }
+        else
+        {
+            // if 2 digit containing hexadecimal
+            buffer.append( HEXA_CHARS[( 0x0f & ( ch >> 4 ) )] );
+            buffer.append( HEXA_CHARS[( 0x0f & ( ch ) )] );
+        }
+    }
+
+    /**
+     * Add end seperation at logging line's end
+     *
+     * @param hexPart hex decimal part
+     * @param textPart text part
+     * @param ret all part
+     */
+    protected static
+    void
+    lineEnd(
+        final StringBuilder hexPart,
+        final StringBuilder textPart,
+        final StringBuilder ret
+    )
+    {
+        // append separator of area
+        hexPart.append( "     |" );
+
+        // append separator of termination
+        textPart.append( "|\n" );
+
+        // concatencate two area
+        ret.append( hexPart );
+        ret.append( textPart );
+
+        // clean each area
+        hexPart.delete( 0, hexPart.capacity() );
+        textPart.delete( 0, textPart.capacity() );
+    }
+
+    /**
+     * <p>
+     * Convert <code>data</code> in hexadecimal format for logging or readibility
+     *
+     * Output layout<br>
+     * <table>
+     * <tr><td>Address( or offset )</td><td>byte character</td><td>hexadecimal</td></tr>
+     * </table>
+     *
+     * Replace control character to '.'<br>
+     * </p>
+     *
+     * <code>
+     * Logger logger = ...
+     * byte[] dump = ...
+     * logger.debug( StringUtil.text2hexa( dump ) );
+     * </code>
+     *
+     * @param data byte array to convert
+     *
+     * @return converted textual string
+     *
+     * @see #text2hexa(byte[], int, int)
+     */
+    public static
+    String
+    text2hexa(
+        final byte[] data
+    )
+    {
+        if ( null == data )
+        {
+            return NULL_STRING;
+        }
+        return text2hexa( data, 0, data.length );
+    }
+
+    /**
+     * <p>
+     * Convert data from <code>offset</code> to <code>offset</code> + <code>length</code> in hexadecimal format.
+     *
+     * Output layout<br>
+     * <table>
+     * <tr><td>Address( or offset )</td><td>byte character</td><td>hexadecimal</td></tr>
+     * </table>
+     *
+     * Replace control character to '.'<br>
+     * </p>
+     *
+     * @param data byte array to convert
+     * @param offset start position to convert
+     * @param length length to convert
+     *
+     * @return converted textual string
+     */
+    public static
+    String
+    text2hexa(
+        final byte[] data,
+        final int offset,
+        final int length
+    )
+    {
+
+        if ( null == data )
+        {
+            return NULL_STRING;
+        }
+        if ( data.length <= 0 )
+        {
+            return EMPTY_BYTES_STRING;
+        }
+
+        final ByteArrayInputStream reader = new ByteArrayInputStream( data, offset, length );
+        final StringBuilder ret = new StringBuilder();
+        final StringBuilder hexPart = new StringBuilder();
+        final StringBuilder textPart = new StringBuilder();
+
+        int address = 0;
+        int ch = -1;
+        int printByte = 0;
+        int cnt = 0;
+
+        // fill white space( ' ' ) in address title
+        hexPart.append( "          " );
+
+        // make horizontal ruler
+        for ( int i = 0, n = WIDTH_PER_LINE / 4 ; i < n ; i++ )
+        {
+            hexPart.append( "+-------" );
+            textPart.append( "+---" );
+        }
+
+        lineEnd( hexPart, textPart, ret );
+
+        while ( 0 <= ( ch = reader.read() ) )
+        {
+            if ( 0 == cnt )
+            {
+                // calculate and print out start address
+                for ( int i = N_INT_BY_BYTE - 1 ; i >= 0 ; i-- )
+                {
+                    printByte = 0xFF & ( address >> ( 8 * i ) );
+                    appendHexa( hexPart, printByte );
+                }
+                hexPart.append( "  " );
+                address += WIDTH_PER_LINE;
+            }
+
+            appendHexa( hexPart, ch );
+            if ( ( ch & 0x80 ) != 0 || ch < 32 )
+            {    // if ch is control character
+                // print out replaced character
+                textPart.append( CONTROL_CHARS_SHOWER );
+            }
+            else
+            {
+                textPart.append( (char) ch );
+            }
+            cnt++;
+
+            if ( WIDTH_PER_LINE == cnt )
+            {
+                lineEnd( hexPart, textPart, ret );
+                cnt = 0;
+            }
+        } // END of while ( 0 <= (ch = reader.read() ) )
+
+        // fill white space( ' ' ) in remaining area
+        if ( 0 != cnt )
+        {
+            for ( ; cnt < WIDTH_PER_LINE ; ++cnt )
+            {
+                hexPart.append( "  " );
+                textPart.append( ' ' );
+            }
+            lineEnd( hexPart, textPart, ret );
+        }
+
+        return ret.toString();
+    }
+
+
+    /* Check & Verification */
+    /**
+     * Check that <code>str</code> is <code>null</code> or empty string textually
+     *
+     * @param str string to check
+     *
+     * @return <code>true</code> if <code>str</code> is null or empty string or string containing only white space
+     *
+     * @see StringUtil#hasText( CharSequence )
+     */
+    public static
+    boolean
+    isEmpty(
+        final CharSequence str
+    )
+    {
+        if ( null == str )
+        {
+            return true;
+        }
+
+        for ( int i=0, n=str.length() ; i<n ; ++i )
+        {
+            if ( Character.isWhitespace( str.charAt( i ) ) )
+            {
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Get length of string
+     *
+     * Return <code>0</code> if <code>str</code> is <code>null</code>
+     *
+     * @param str string whose length is checked
+     *
+     * @return length of <code>str</code>
+     */
+    public static
+    int
+    size(
+        final CharSequence str
+    )
+    {
+        if ( null == str )
+        {
+            return 0;
+        }
+        return str.length();
+    }
+
+    /**
+     * <p>
+     * Check that <code>str</code> contain any character
+     * </p>
+     * @param str string to check
+     *
+     * @return <code>true</code> if <code>str</code> is not <code>null</code> nor empty string
+     *
+     * @see #size(CharSequence)
+     */
+    public static
+    boolean
+    hasLength(
+        final CharSequence str
+    )
+    {
+        return 0 < size( str );
+    }
+
+    /**
+     * Check that <code>str</code> has textual character
+     *
+     * @param str string to check
+     *
+     * @return <code>true</code> if <code>str</code> has textual character
+     * 
+     * @see isEmpty( CharSequence )
+     */
+    public static
+    boolean
+    hasText(
+        final CharSequence str
+    )
+    {
+        return !isEmpty( str );
+    }
+
+    /* Conversion */
+    /**
+     * Check <code>strs</code> and return non-null string
+     *
+     * Return empty string if all of element in <code>strs</code>
+     *
+     * @param strs strings to check
+     *
+     * @return non-null in <code>strs</code>
+     *
+     * see #ObjectUtil{@link #nvl(String...)}
+     */
+    public static
+    String
+    nvl(
+        final String... strs
+    )
+    {
+        String val = ObjectUtil.nvl( strs );
+        if ( null == val )
+        {
+            return "";
+        }
+        return val;
+    }
+
+    /**
+     * Trim leading whitespaqce
+     *
+     * @param str string to trim
+     *
+     * @return trimmed string
+     */
+    public static
+    String
+    trimLeading(
+        final String str
+    )
+    {
+        if( !hasLength( str ) )
+        {
+            return str;
+        }
+
+        final char[] chs = str.toCharArray();
+        for ( int i=0, n=chs.length ; i<n ; ++i )
+        {
+            if ( !Character.isWhitespace( chs[i] ) )
+            {
+                return new String( chs, i, str.length() - i );
+            }
+        }
+        return EMPTY_STRING;
+    }
+
+    /**
+     * Trim trailing white space
+     *
+     * @param str string to trim
+     *
+     * @return trimmed string
+     */
+    public static
+    String
+    trimTrailing(
+        final String str
+    )
+    {
+        if( !hasLength( str ) )
+        {
+            return str;
+        }
+
+        final char[] chs = str.toCharArray();
+        for ( int i=chs.length-1, j=chs.length ; 0<j ; --i, --j )
+        {
+            if ( !Character.isWhitespace( chs[i] ) )
+            {
+                return new String( chs, 0, j );
+            }
+        }
+        return EMPTY_STRING;
+    }
+    /**
+     * Remove white spaces at leading and trailing part of <code>str</code>
+     *
+     * Return empty string if <code>str</code> is <code>null</code>
+     *
+     * @param str string to convert
+     *
+     * @return converted string
+     *
+     * @see StringUtil#trimLeading(String)
+     * @see StringUtil#trimTrailing(String)
+     */
+    public static
+    String
+    trim(
+        final String str
+    ) {
+        return trimTrailing( trimLeading( str ) );
+    }
+
+    /**
+     * Convert <code>str</code> to meaningful for search
+     *
+     * @param str string to convert
+     *
+     * @return converted string
+     */
+    public static
+    String
+    getMeaningful(
+        final String str
+    ) {
+        if ( null == str )
+        {
+            return EMPTY_STRING;
+        }
+        return trim( str ).toLowerCase();
+    }
+
+    /**
+     * Mask <code>str</code> with <code>maskingStr</code>
+     *
+     * Replace <code>str</code> to <code>maskingStr</code> with <code>str</code>'s length
+     *
+     * @param str string to mask
+     * @param maskingStr string to mask with
+     *
+     * @return masked string
+     */
+    public static
+    String
+    mask(
+        final String str,
+        final String maskingStr
+    ) {
+        if ( null == str )
+        {
+            return "null";
+        }
+
+        final StringBuilder buffer = new StringBuilder();
+        for ( int i=0, n=str.length() ; i<n ; ++i )
+        {
+            buffer.append( maskingStr );
+        }
+        return buffer.toString();
+    }
+
+    /* Analysis & Extract */
+    /**
+     * Extract <code>targetIndex</code> string from strings
+     *
+     * where <code>str</code> is splitted by <code>delimeter</code>
+     *
+     * @param str string with <code>delimeter</code>
+     * @param delimeter what split <code>str</code> with
+     * @param escaper escape character for <code>delimter</code>
+     * @param targetIndex index from fragments
+     *
+     * @return extracted string
+     */
+    public static
+    String
+    getParamater(
+        final String str,
+        final char delimeter,
+        final int escaper,
+        final int targetIndex
+    )
+    throws IOException
+    {
+        try
+        {
+            if ( null == str )
+            {
+                return null;
+            }
+            final StringReader reader = new StringReader( str );
+            StringWriter writer = null;
+            int ch = 0;
+            final int ST_NORMAL = 0;
+            final int ST_ESCAPE = 1;
+            int status = ST_NORMAL;
+            int index = 0;
+            if ( 0 == targetIndex )
+            {
+                writer = new StringWriter();
+            }
+            while ( 0 <= ( ch = reader.read() ) ) {
+                if ( ST_ESCAPE == status ) {
+                    status = ST_NORMAL;
+                } else {
+                    if ( escaper == ch ) {
+                        status = ST_ESCAPE;
+                        continue;
+                    } else if ( delimeter == ch ) {
+                        if ( index == targetIndex )
+                        {
+                            return writer.toString();
+                        }
+                        ++index;
+                        if ( index == targetIndex )
+                        {
+                            writer = new StringWriter();
+                        }
+                        continue;
+                    }
+                }
+                if ( null != writer )
+                {
+                    writer.write( (int) ch );
+                }
+            }
+            if ( index == targetIndex )
+            {
+                return writer.toString();
+            }
+            return null;
+        }
+        catch ( final IOException e )
+        {
+            // Never throw
+            throw new IllegalStateException( e );
+        }
+    }
+
+    /**
+     * Return substring starting <code>indexFromLast</code> from last
+     *
+     * @param str original string
+     * @param indexFromLast starting index from last
+     *
+     * @return substring
+     */
+    public static
+    String
+    lastSubstring(
+        final String str,
+        final int indexFromLast
+    )
+    {
+        if ( null == str )
+        {
+            return null;
+        }
+
+        final int length = str.length();
+
+        if ( length < indexFromLast )
+        {
+            return str;
+        }
+
+        return str.substring( length - indexFromLast );
+    }
+
+    /**
+     * Extract last fragment in strings split <code>str</code> with <code>separator</code>
+     *
+     * @param str origin string
+     * @param separator string for separation
+     *
+     * @return last fragment string
+     */
+    public static
+    String
+    getLastSegment(
+        final String str,
+        final String separator
+    )
+    {
+        if ( null == str )
+        {
+            return EMPTY_STRING;
+        }
+
+        final int index = str.lastIndexOf( separator );
+        if ( index < 0 )
+        {
+            return str;
+        }
+
+        return str.substring( index + separator.length() );
+    }
+
+    /**
+     * Extract last fragment in string and return remaining string with <code>separator</code>
+     *
+     * @param str origin string
+     * @param separator string for separation
+     *
+     * @return remaining string
+     */
+    public static
+    String
+    removeLastSegment(
+        final String str,
+        final String separator
+    )
+    {
+        if ( null == str )
+        {
+            return EMPTY_STRING;
+        }
+
+        final int index = str.lastIndexOf( separator );
+
+        if ( index < 0 )
+        {
+            return EMPTY_STRING;
+        }
+
+        return str.substring( 0, index );
+
+    }
+
+    /**
+     * Make <code>n</code> repeated <code>symbol</code> string
+     *
+     * @param symbol composing string
+     * @param n repeat count
+     *
+     * @return made string
+     */
+    public static
+    String
+    multiply(
+        final String symbol,
+        final int n
+    )
+    {
+        if ( null == symbol ) {
+            return EMPTY_STRING;
+        }
+
+        final StringBuilder buffer = new StringBuilder();
+        for ( int i=0 ; i<n ; ++i )
+        {
+            buffer.append( symbol );
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Check that <code>str</code> contain white spaces
+     *
+     * @param str string to check
+     * @return <code>true</code> if <code>str</code> contain white spaces
+     */
+    public static
+    boolean
+    containsWhitespace(
+        final CharSequence str
+    )
+    {
+        final int nChar = size( str );
+
+        for ( int i= 0; i< nChar; ++i )
+        {
+            if ( Character.isWhitespace( str.charAt( i ) ) )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * Trim leading <code>leadingCharacter</code> from <code>str</code>
+     *
+     * @param str string to trim
+     * @param leadingCharacter character to trim with
+     *
+     * @return trimmed string
+     */
+    public static
+    String
+    trimLeadingCharacter(
+        final String str,
+        final char leadingCharacter
+    )
+    {
+        if( !hasLength( str ) )
+        {
+            return str;
+        }
+
+        final char[] chs = str.toCharArray();
+        for ( int i=0, n=chs.length ; i<n ; ++i )
+        {
+            if ( leadingCharacter != chs[i] )
+            {
+                return new String( chs, i, str.length() - i );
+            }
+        }
+        return EMPTY_STRING;
+    }
+
+    /**
+     * Trim trailing <code>trailingCharacter</code> from <code>str</code>
+     *
+     * @param str string to trim
+     * @param trailingCharacter character to trim with
+     *
+     * @return trimmed string
+     */
+    public static
+    String
+    trimTrailingCharacter(
+        final String str,
+        final char trailingCharacter
+    )
+    {
+        if( !hasLength( str ) )
+        {
+            return str;
+        }
+
+        final char[] chs = str.toCharArray();
+        for ( int i=chs.length-1, j=chs.length ; 0<j ; --i, --j )
+        {
+            if ( trailingCharacter != chs[i] )
+            {
+                return new String( chs, 0, j );
+            }
+        }
+        return EMPTY_STRING;
+    }
+
+    /**
+     * Trim <code>str</code> with <code>character</code>
+     *
+     * @param str string to trim
+     * @param character character to trim with
+     *
+     * @return trimmed string
+     */
+    public static
+    String
+    trimCharacter(
+        final String str,
+        final char character
+    )
+    {
+        return trimTrailingCharacter( trimLeadingCharacter( str, character ), character );
+    }
+
+    /**
+     * Extract word at <coode>index</code> column in <code>doc</code>
+     *
+     * @param doc full string
+     * @param index column index
+     *
+     * @return word at <code>index</code> column
+     */
+    public static
+    String
+    getWord(
+        final String doc,
+        final int index
+    )
+    {
+        final StringBuilder buffer = new StringBuilder();
+
+        int position = index;
+
+        if ( doc.length() < index )
+        {
+            return "";
+        }
+
+        for ( int i = position - 1 ; 0 <= i ; --i )
+        {
+
+            int ch = doc.charAt( i );
+
+            if ( Character.isWhitespace( ch ) )
+            {
+                break;
+            }
+            buffer.append( (char) ch );
+        }
+        buffer.reverse();
+
+        for ( int i = position , n = doc.length() ; i < n ; ++i )
+        {
+            int ch = doc.charAt( i );
+            if ( Character.isWhitespace( ch ) )
+            {
+                break;
+            }
+            buffer.append( (char) ch );
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * Enum to String array
+     *
+     * @param values enum values
+     *
+     * @return string array
+     */
+    public static <T extends Enum<T>> String[] enumNameToStringArray(T[] values) {
+        int i = 0;
+        String[] result = new String[values.length];
+        for (T value: values) {
+            result[i++] = value.name();
+        }
+        return result;
+    }
+
+    /**
+     * Returns <code>true</code> if the given str is set of integers. Or {@code false} otherwise.
+     * 
+     */
+    public static boolean isInteger(String str) {
+        try {
+            Integer.parseInt(str);
+            return true;
+        } catch (NumberFormatException e) {
+            return false;
+        }
+    }
+    
+    /**
+     * Returns string with first letter converted to upper case.
+     * @param str
+     * @return
+     */
+    public static String convertFirstLetterUpperCase(String str) {
+        if (isEmpty(str))
+            return null;
+       
+        char[] str_array = str.toCharArray();
+        str_array[0] = Character.toUpperCase(str_array[0]);
+        str = new String(str_array);
+        return str;
+    }
+    
+    /**
+     * Returns last string after  <code>lastIndexStr</code> from <code>input</code>.
+     * For example, if <code>input</code>  is "HOME/File", and <code>lastIndexStr</code> is "/" then, it returns File.
+     * 
+     * @param input input string
+     * @param lastIndexStr string indicates last string
+     * @return
+     */
+    public static String getLastStringAfter(String input, String lastIndexStr) {
+        if (input == null) {
+            return null;
+        }
+        
+        if ( null == lastIndexStr )
+        {
+               return null;
+        }
+
+        int k = input.lastIndexOf(lastIndexStr);
+
+        return (k != -1) ? input.substring(k + lastIndexStr.length(), input.length()) : null;
+    }
+}
index d261ab1..4fd74d3 100755 (executable)
@@ -214,7 +214,12 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Import-Package: 
  org.eclipse.jface.text,
  org.eclipse.ui.console,
- org.tizen.sdblib
+ org.tizen.sdblib,
+ org.tizen.sdblib.daemon,
+ org.tizen.sdblib.exception,
+ org.tizen.sdblib.receiver,
+ org.tizen.sdblib.service,
+ org.tizen.sdblib.util
 Bundle-Activator: org.tizen.common.CommonPlugin
 Bundle-ActivationPolicy: lazy
 Bundle-ClassPath: .,
index 40c763b..5f411c7 100755 (executable)
@@ -46,9 +46,10 @@ import org.tizen.common.util.DialogUtil;
 import org.tizen.common.util.HostUtil;
 import org.tizen.common.util.OSChecker;
 import org.tizen.common.util.log.TizenLog4jConfigurator;
-import org.tizen.sdblib.CrashReportService;
 import org.tizen.sdblib.ICrashReportServiceListener;
 import org.tizen.sdblib.SmartDevelopmentBridge;
+import org.tizen.sdblib.exception.ServerException;
+import org.tizen.sdblib.service.CrashReportService;
 
 /**
  * Log.
@@ -74,6 +75,9 @@ public class CommonPlugin extends AbstractUIPlugin {
     protected Executor executor = null;
     
     protected RepositorySelector selector = null;
+    
+    protected CrashReportService crService = null;
+
 
     /*
      * (non-Javadoc)
@@ -94,7 +98,6 @@ public class CommonPlugin extends AbstractUIPlugin {
         }
         else {
             try {
-                SmartDevelopmentBridge.init();
                 SmartDevelopmentBridge.createBridge(sdbPath, true);
             } catch (Throwable t) {
                 plugin.getLog().log(new Status(Status.ERROR, PLUGIN_ID, "Problem occurred while initializing sdb", t));
@@ -102,6 +105,9 @@ public class CommonPlugin extends AbstractUIPlugin {
             }
         }
 
+        initializeSmartDeviceBridge();
+        initializeCrashReportService();
+        
         if (OSChecker.isWindows()) {
             String dllPath = InstallPathConfig.getSdbWinUsbApiPath();
             if (!HostUtil.exists(dllPath)) {
@@ -109,7 +115,7 @@ public class CommonPlugin extends AbstractUIPlugin {
                         "It's not mandatory but you may have problem in using sdb through USB.");
             }
         }
-        addCSCreateListener();
+
     }
 
     /*
@@ -118,6 +124,7 @@ public class CommonPlugin extends AbstractUIPlugin {
      */
     @Override
     public void stop(BundleContext context) throws Exception {
+       finalizeSmartDeviceBridge();
         finalizeExecutor();
         plugin = null;
         super.stop(context);
@@ -184,7 +191,33 @@ public class CommonPlugin extends AbstractUIPlugin {
     protected void finalizeExecutor() {
     }
 
-    private void addCSCreateListener() {
+    protected void initializeSmartDeviceBridge()
+    {
+        String sdbPath = InstallPathConfig.getSDBPath();
+        if (!HostUtil.exists(sdbPath))
+        {
+               DialogUtil.openMessageDialog(String.format("There is no %s.", sdbPath));
+        }
+        else {
+            try
+            {
+                SmartDevelopmentBridge.createBridge(sdbPath, true);
+            }
+            catch ( final Throwable t )
+            {
+               plugin.getLog().log(new Status(Status.ERROR, PLUGIN_ID, "Problem occurred while initializing sdb", t));
+                DialogUtil.openErrorDialog("Failed to start sdb");
+            }
+        }
+    }
+       
+       protected void finalizeSmartDeviceBridge()
+       {
+               SmartDevelopmentBridge.disconnectBridge();
+       }
+       
+    protected void initializeCrashReportService() throws ServerException {
+       crService = new CrashReportService();
         final String EXT_ID = "org.tizen.common.crashreporter";
         final String ATTR_SCOPE = "client";
         final String ATTR_CLASS = "class";
@@ -192,20 +225,26 @@ public class CommonPlugin extends AbstractUIPlugin {
         IExtensionRegistry x = RegistryFactory.getRegistry();
         IConfigurationElement[] ces = x.getConfigurationElementsFor(EXT_ID);
 
-        for (IConfigurationElement ce : ces) {
+        for ( IConfigurationElement ce : ces ) {
             if (ATTR_SCOPE.equals(ce.getName())) {
                 String className = ce.getAttribute(ATTR_CLASS);
                 if (className != null) {
                     try {
                         Object obj = ce.createExecutableExtension(ATTR_CLASS);
                         if (obj instanceof ICrashReportServiceListener) {
-                            CrashReportService.addCrashReportServiceListener((ICrashReportServiceListener)obj);
+                            crService.addCrashReportServiceListener( (ICrashReportServiceListener) obj );
                         }
                     } catch (CoreException e) {
-                        plugin.getLog().log(new Status(Status.WARNING, PLUGIN_ID, "Problem occurred while adding CrashReportServiceListener", e));
+                       plugin.getLog().log( new Status( Status.WARNING, PLUGIN_ID, "Error occurred while adding cs create listener" , e ) );
                     }
                 }
             }
         }
+        crService.boot();
+    }
+    
+    protected void destroyCrashReportService()
+    {
+       crService.down();
     }
 }
index c9ee84e..831f8da 100644 (file)
@@ -32,10 +32,10 @@ import org.tizen.common.core.command.Executor;
 import org.tizen.common.util.Assert;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.SdbCommandRejectedException;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
-import org.tizen.sdblib.SyncService.SyncResult;
 import org.tizen.sdblib.TimeoutException;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.service.SyncService.SyncResult;
 
 public class PullSdbCommand
 extends SdbDevicesHandlingCommand
index f5cfc8b..2115c95 100755 (executable)
@@ -33,10 +33,10 @@ import org.tizen.common.util.Assert;
 import org.tizen.common.util.FilenameUtil;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.SdbCommandRejectedException;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
-import org.tizen.sdblib.SyncService.SyncResult;
 import org.tizen.sdblib.TimeoutException;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.service.SyncService.SyncResult;
 
 public class PushSdbCommand
 extends SdbDevicesHandlingCommand
index 647ef49..44a8682 100644 (file)
@@ -29,7 +29,7 @@ import org.tizen.common.core.command.ExecutionContext;
 import org.tizen.common.core.command.Executor;
 import org.tizen.common.util.Assert;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.MultiLineReceiver;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
 
 /**
  * <p>
index 2709e20..36e41c0 100755 (executable)
@@ -47,10 +47,6 @@ public class SmartDevelopmentBridgeManager
         return impl.equals(obj);
     }
 
-    public int getConnectionAttemptCount() {
-        return impl.getConnectionAttemptCount();
-    }
-
     public IDevice[] getDevices() {
         return impl.getDevices();
     }
index fcb07ce..1d9e442 100755 (executable)
@@ -51,8 +51,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.tizen.common.util.IOUtil;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.SyncResult;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.SyncResult;
 
 /**
  * Delta Detector for Rapid Development Support.
index 0c8bc17..ce80255 100644 (file)
@@ -47,8 +47,8 @@ import org.tizen.common.sdb.command.receiver.PkgCmdReceiver;
 import org.tizen.common.ui.view.console.ITizenConsoleManager;
 import org.tizen.common.util.ISdbCommandHelper;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.SyncResult;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.SyncResult;
 
 /**
  * This class deploys delta resource of project to target.
index 6721faf..34e8b08 100644 (file)
@@ -1,7 +1,7 @@
 package org.tizen.common.sdb.command.receiver;
 
 import org.tizen.common.ui.view.console.ITizenConsoleManager;
-import org.tizen.sdblib.MultiLineReceiver;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
 
 public class CommandOutputReceiver extends MultiLineReceiver {
     protected StringBuilder commandOutput = new StringBuilder(256);
@@ -10,7 +10,7 @@ public class CommandOutputReceiver extends MultiLineReceiver {
 
     public CommandOutputReceiver(ITizenConsoleManager console) {
         super();
-        setTrimLine(false);
+        setTrimLines(false);
         this.console = console;
     }
 
index 401c0f5..a036d8c 100644 (file)
 */
 package org.tizen.common.core.command.sdb;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import org.junit.Test;
 import org.tizen.common.core.command.CommandTest;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.MultiLineReceiver;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
 
 /**
  * DlogSdbCommandTest
index c434fcb..554693b 100755 (executable)
@@ -37,9 +37,9 @@ import org.powermock.modules.junit4.PowerMockRunner;
 import org.tizen.common.core.command.CommandTest;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.SdbCommandRejectedException;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.SyncResult;
 import org.tizen.sdblib.TimeoutException;
+import org.tizen.sdblib.service.SyncService;
+import org.tizen.sdblib.service.SyncService.SyncResult;
 
 /**
  * PullSdbCommandTest
index f37820f..ac7871c 100644 (file)
@@ -34,8 +34,8 @@ import org.junit.Test;
 import org.tizen.common.core.command.CommandTest;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.SdbCommandRejectedException;
-import org.tizen.sdblib.SyncService;
 import org.tizen.sdblib.TimeoutException;
+import org.tizen.sdblib.service.SyncService;
 
 /**
  * PushSdbCommandTest
index db72653..629d7a5 100644 (file)
 */
 package org.tizen.common.core.command.sdb;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import org.junit.Test;
 import org.tizen.common.core.command.CommandTest;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.MultiLineReceiver;
+import org.tizen.sdblib.receiver.MultiLineReceiver;
 
 /**
  * ShellSdbCommandTest