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,
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;
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}.
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.
*/
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;
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;
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
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
{
* @see IDeviceChangeListener#deviceConnected(IDevice)
*/
@Override
- public void deviceConnected(IDevice device)
+ public void onConnected(IDevice device)
{
if (device.isOffline())
{
}
@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);
}
}
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
{
}
@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)
}
@Override
- public void deviceChanged(final IDevice device, int changeMask)
+ public void onChanged(final IDevice device, int changeMask)
{
if (changeMask == 1)
{
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
{
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
{
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()
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);
}
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);
{
super();
- setTrimLine(false);
+ setTrimLines(false);
}
@Override
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
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()
{
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);
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 {
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 {
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 {
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 {
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 {
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.
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
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 {
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 {
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 {
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
--- /dev/null
+/*\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
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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
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
}
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;
}
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 {
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) {
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;
/*
- * 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;
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;
* 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
return mMonitoring;
}
- int getConnectionAttemptCount() {
- return mConnectionAttempt;
- }
-
int getRestartAttemptCount() {
return mRestartAttemptCount;
}
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 {
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;
}
/**
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).
}
}
}
- }
+// }
newList.clear();
}
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();
+ }
+
+ }
+
}
--- /dev/null
+/*\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
--- /dev/null
+/*\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
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. */
/** 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.
*/
String getDeviceName();
+ /**
+ * Return the state of the device
+ *
+ * @return state of the device
+ *
+ * @see DeviceState
+ */
DeviceState getState();
/**
boolean isEmulator();
/**
+ * Returns architecture of the device
* Returns {@link Arch} about device architecture.
*/
Arch getArch();
*
* @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
* @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,
* 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)
--- /dev/null
+/*\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
/*
- * 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();
};
import java.security.InvalidParameterException;
+import org.tizen.sdblib.util.ArrayHelper;
+
/**
* Receiver able to provide low level parsing for device-side log services.
*/
* of {@link LogEntry} objects.
* @param listener the listener to receive new log entries.
*/
- public LogReceiver(ILogListener listener) {
+ private LogReceiver(ILogListener listener) {
mListener = listener;
}
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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;
- }
-
-}
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.
* <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.
* 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;
* @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();
* 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 {
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
byte[] data = new byte[16384];
ByteBuffer buf = ByteBuffer.wrap(data);
int timeToResponseCount = 0;
+ final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
while (true) {
int count;
// 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");
}
}
* 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
* @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
}
}
} finally {
+ tryClose( sdbChan );
if (sdbChan != null) {
sdbChan.close();
}
/**
* 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.
* @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$
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.
* @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$
throw new SdbCommandRejectedException(resp.message);
}
} finally {
+ tryClose( sdbChan );
if (sdbChan != null) {
sdbChan.close();
}
* @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());
}
/**
* @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;
* @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());
}
/**
* @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;
* @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
--- /dev/null
+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
+++ /dev/null
-/*
- * 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();
- }
-}
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
* <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;
protected Lock lock = new ReentrantLock();
private boolean mStarted = false;
- private DeviceMonitor mDeviceMonitor;
+ private DeviceMonitor deviceMonitor;
private final static ArrayList<IDebugBridgeChangeListener> sBridgeListeners =
new ArrayList<IDebugBridgeChangeListener>();
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)}.
* @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);
+ }
}
/**
*/
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/>
* @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
// 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;
}
}
* 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() {
*/
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
// 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);
}
}
}
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);
}
}
}
{
if(device.isOnline())
{
- listener.deviceConnected(device);
+ listener.onConnected(device);
}
}
}
*/
public IDevice[] getDevices() {
synchronized (sLock) {
- if (mDeviceMonitor != null) {
- return mDeviceMonitor.getDevices();
+ if (deviceMonitor != null) {
+ return deviceMonitor.getDevices();
}
}
* {@link IDeviceChangeListener} object.
*/
public boolean hasInitialDeviceList() {
- if (mDeviceMonitor != null) {
- return mDeviceMonitor.hasInitialDeviceList();
+ if (deviceMonitor != null) {
+ return deviceMonitor.hasInitialDeviceList();
}
return false;
* 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;
}
*/
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;
+ }
}
/**
}
// kill the monitoring services
- mDeviceMonitor.stop();
- mDeviceMonitor = null;
+ deviceMonitor.down();
+ deviceMonitor = null;
if (stopSdb() == false) {
return false;
*/
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;
}
boolean restart = startSdb();
- if (restart && mDeviceMonitor == null) {
- mDeviceMonitor = new DeviceMonitor(this);
- mDeviceMonitor.start();
+ if (restart && deviceMonitor == null) {
+ start();
}
return restart;
// 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);
}
}
}
// 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);
}
}
}
// 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);
}
}
}
* Returns the {@link DeviceMonitor} object.
*/
DeviceMonitor getDeviceMonitor() {
- return mDeviceMonitor;
+ return deviceMonitor;
}
/**
*/
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;
}
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;
}
*/
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;
}
}
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;
}
* @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$
while (true) {
String line = errReader.readLine();
if (line != null) {
- Log.e(SDB, line);
- errorOutput.add(line);
+ Log.e(TAG_SDB, line);
} else {
break;
}
while (true) {
String line = outReader.readLine();
if (line != null) {
- Log.d(SDB, line);
- stdOutput.add(line);
+ Log.d(TAG_SDB, line);
} else {
break;
}
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();
}
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())
--- /dev/null
+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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*
+ * 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 );
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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
/*
- * 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;
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$
*/
public boolean isAppFileName()
{
- Matcher m = sApkPattern.matcher(name);
+ Matcher m = PKG_PATTERN.matcher(name);
return m.matches();
}
* 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
{
* @param device
* The Device the service is connected to.
*/
- FileListingService(Device device)
+ public FileListingService(Device device)
{
mDevice = device;
}
* limitations under the License.
*/
-package org.tizen.sdblib;
+package org.tizen.sdblib.service;
import java.io.Closeable;
import java.io.File;
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;
/**
}
}
- private final InetSocketAddress mAddress;
+ private final SmartDevelopmentBridge sdb;
private final Device mDevice;
private SocketChannel mChannel;
* @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;
}
* @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 */);
*/
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());
}
/**
*/
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());
}
/**
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");
}
--- /dev/null
+/*
+ * 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 );
+ }
+}
--- /dev/null
+/*
+ * 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, "" );
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*\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
/*
- * 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;
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
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];
}
}
- 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.
/* 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 {
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)
--- /dev/null
+/*\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
--- /dev/null
+/*
+ * 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();
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+* 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;
+ }
+
+ }
+
+}
/*
- * 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.
* 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;
}
/**
* @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.
}
}
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import org.tizen.sdblib.Log;
public class SdbShellProcess extends Process {
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
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: .,
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.
protected Executor executor = null;
protected RepositorySelector selector = null;
+
+ protected CrashReportService crService = null;
+
/*
* (non-Javadoc)
}
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));
}
}
+ initializeSmartDeviceBridge();
+ initializeCrashReportService();
+
if (OSChecker.isWindows()) {
String dllPath = InstallPathConfig.getSdbWinUsbApiPath();
if (!HostUtil.exists(dllPath)) {
"It's not mandatory but you may have problem in using sdb through USB.");
}
}
- addCSCreateListener();
+
}
/*
*/
@Override
public void stop(BundleContext context) throws Exception {
+ finalizeSmartDeviceBridge();
finalizeExecutor();
plugin = null;
super.stop(context);
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";
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();
}
}
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
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
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>
return impl.equals(obj);
}
- public int getConnectionAttemptCount() {
- return impl.getConnectionAttemptCount();
- }
-
public IDevice[] getDevices() {
return impl.getDevices();
}
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.
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.
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);
public CommandOutputReceiver(ITizenConsoleManager console) {
super();
- setTrimLine(false);
+ setTrimLines(false);
this.console = console;
}
*/
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
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
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
*/
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